Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: lib/rules.js

Issue 8450003: Reimplemented whitelist handling (Closed)
Patch Set: Created Sept. 25, 2012, 3:48 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* This Source Code Form is subject to the terms of the Mozilla Public 1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 4
5 Cu.import("resource://gre/modules/Services.jsm"); 5 Cu.import("resource://gre/modules/Services.jsm");
6 Cu.import("resource://gre/modules/FileUtils.jsm"); 6 Cu.import("resource://gre/modules/FileUtils.jsm");
7 7
8 let {Prefs} = require("prefs"); 8 let {Prefs} = require("prefs");
9 9
10 let RULES_VERSION = 2; 10 let RULES_VERSION = 2;
11 11
12 let CUSTOM_RULE_PRIORITY = 0x7FFFFFFF;
13
12 let rules = {expressions: []}; 14 let rules = {expressions: []};
13 15
14 loadRules(); 16 loadRules();
15 17
16 // Make first attempt to update rules after five minutes 18 // Make first attempt to update rules after five minutes
17 let updateTimer = null; 19 let updateTimer = null;
18 updateTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 20 updateTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
19 updateTimer.initWithCallback(onTimer, 1000 * 60 * 5, Ci.nsITimer.TYPE_REPEATING_ SLACK); 21 updateTimer.initWithCallback(onTimer, 1000 * 60 * 5, Ci.nsITimer.TYPE_REPEATING_ SLACK);
20 onShutdown.add(function() updateTimer.cancel()); 22 onShutdown.add(function() updateTimer.cancel());
21 23
(...skipping 17 matching lines...) Expand all
39 request.addEventListener("load", function() 41 request.addEventListener("load", function()
40 { 42 {
41 try 43 try
42 { 44 {
43 // Remove comments from the file if any 45 // Remove comments from the file if any
44 let data = JSON.parse(request.responseText.replace(/^\s*\/\/.*/mg, "")); 46 let data = JSON.parse(request.responseText.replace(/^\s*\/\/.*/mg, ""));
45 if (ignoreVersion || data.version == RULES_VERSION) 47 if (ignoreVersion || data.version == RULES_VERSION)
46 { 48 {
47 rules = data; 49 rules = data;
48 callback(true); 50 callback(true);
51
52 // Add user-defined rules after calling the callback - if the callback
53 // saves the rules then the custom rules won't be included.
54 addCustomRules();
49 } 55 }
50 else 56 else
51 callback(false); 57 callback(false);
52 } 58 }
53 catch (e) 59 catch (e)
54 { 60 {
55 Cu.reportError(e); 61 Cu.reportError(e);
56 callback(false); 62 callback(false);
57 } 63 }
58 }, false); 64 }, false);
(...skipping 15 matching lines...) Expand all
74 } 80 }
75 81
76 function getRuleFile() 82 function getRuleFile()
77 { 83 {
78 let result = FileUtils.getFile("ProfD", ["url-fixer-rules.json"]); 84 let result = FileUtils.getFile("ProfD", ["url-fixer-rules.json"]);
79 85
80 getRuleFile = function() result; 86 getRuleFile = function() result;
81 return getRuleFile(); 87 return getRuleFile();
82 } 88 }
83 89
90 function addCustomRules()
91 {
92 for (let domain in Prefs.whitelist)
93 onWhitelistEntryAdded(domain);
94 }
95
96 function onWhitelistEntryAdded(domain)
97 {
98 let reverse = Array.prototype.slice.call(domain).reverse().join("");
Thomas Greiner 2012/09/26 15:59:35 also in onWhitelistEntryAdded function
99 addSuffix(rules.domain, reverse, CUSTOM_RULE_PRIORITY);
100 }
101 exports.onWhitelistEntryAdded = onWhitelistEntryAdded;
102
103 function onWhitelistEntryRemoved(domain)
104 {
105 let reverse = Array.prototype.slice.call(domain).reverse().join("");
Thomas Greiner 2012/09/26 15:49:13 It looks less confusing if you do it this way: le
Wladimir Palant 2012/09/27 14:55:06 domain is a string - string.slice() returns anothe
106 removeSuffix(rules.domain, reverse, CUSTOM_RULE_PRIORITY);
107 }
108 exports.onWhitelistEntryRemoved = onWhitelistEntryRemoved;
109
110 function addSuffix(tree, suffix, priority)
111 {
112 if (suffix.length == 0)
113 {
114 // We are at the last character, just put our priority here
115 tree[""] = " " + priority;
116 return;
117 }
118
119 let c = suffix[0];
120 if (c in tree)
121 {
122 let existing = tree[c];
123 if (typeof existing == "string")
124 {
125 // Single choice for this suffix, maybe the same entry?
126 if (existing.substr(0, suffix.length - 1) == suffix.substr(1) && existing[ suffix.length - 1] == " ")
127 {
128 // Same entry, simply replace it by new priority
129 tree[c] = suffix.substr(1) + " " + priority;
130 }
131 else
132 {
133 // Different entry, need to add a new branching point and go deeper
134 if (existing[0] == " ")
135 tree[c] = {"": existing};
136 else
137 {
138 tree[c] = {};
139 tree[c][existing[0]] = existing.substr(1);
140 }
141 addSuffix(tree[c], suffix.substr(1), priority);
142 }
143 }
144 else
145 {
146 // Multiple choices for this suffix - go deeper
147 addSuffix(existing, suffix.substr(1), priority);
148 }
149 }
150 else
151 {
152 // No existing entry yet, just add ours
153 tree[c] = suffix.substr(1) + " " + priority;
154 }
155 }
156
157 function removeSuffix(tree, suffix, priority)
158 {
159 if (suffix.length == 0)
160 {
161 // We are at the last character, check whether there is an entry with
162 // matching priority
163 if ("" in tree && tree[""] == " " + priority)
164 delete tree[""];
165 return;
166 }
167
168 let c = suffix[0];
169 if (!(c in tree))
170 return;
171
172 if (typeof tree[c] == "string")
173 {
174 // Single entry - check whether it is the right one
175 if (tree[c] == suffix.substr(1) + " " + priority)
176 delete tree[c];
177 }
178 else
179 {
180 // Multiple entries, need to go deeper
181 removeSuffix(tree[c], suffix.substr(1), priority);
182 }
183 }
184
84 function onTimer() 185 function onTimer()
85 { 186 {
86 // Next check in 1 hour 187 // Next check in 1 hour
87 updateTimer.delay = 1000 * 60 * 60; 188 updateTimer.delay = 1000 * 60 * 60;
88 189
89 // Only download rules every three days 190 // Only download rules every three days
90 let nextUpdate = Prefs.lastRuleUpdate + 60 * 60 * 24 * 3; 191 let nextUpdate = Prefs.lastRuleUpdate + 60 * 60 * 24 * 3;
91 if (nextUpdate > Date.now() / 1000) 192 if (nextUpdate > Date.now() / 1000)
92 return; 193 return;
93 194
94 loadRulesFrom("http://urlfixer.org/download/rules.json?version=" + RULES_VERSI ON, false, function(success) 195 loadRulesFrom("http://urlfixer.org/download/rules.json?version=" + RULES_VERSI ON, false, function(success)
95 { 196 {
96 if (success) 197 if (success)
97 { 198 {
98 rules.timestamp = Date.now(); 199 rules.timestamp = Date.now();
99 200
100 var dynRules = require("updateRules").updateRules();
101 for(var i in dynRules)
102 {
103 rules[i] = dynRules[i];
104 }
105
106 try 201 try
107 { 202 {
108 // Save the rules to file. 203 // Save the rules to file.
109 let rulesText = JSON.stringify(rules); 204 let rulesText = JSON.stringify(rules);
110 let fileStream = FileUtils.openSafeFileOutputStream(getRuleFile()); 205 let fileStream = FileUtils.openSafeFileOutputStream(getRuleFile());
111 let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createIns tance(Ci.nsIConverterOutputStream); 206 let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createIns tance(Ci.nsIConverterOutputStream);
112 stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAU LT_REPLACEMENT_CHARACTER); 207 stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAU LT_REPLACEMENT_CHARACTER);
113 stream.writeString(rulesText); 208 stream.writeString(rulesText);
114 stream.flush(); 209 stream.flush();
115 FileUtils.closeSafeFileOutputStream(fileStream); 210 FileUtils.closeSafeFileOutputStream(fileStream);
(...skipping 27 matching lines...) Expand all
143 let customRules = Prefs.custom_replace; 238 let customRules = Prefs.custom_replace;
144 for (let searchString in customRules) 239 for (let searchString in customRules)
145 { 240 {
146 let replacement = customRules[searchString]; 241 let replacement = customRules[searchString];
147 searchString = searchString.toLowerCase(); 242 searchString = searchString.toLowerCase();
148 if (/^re:+/.test(searchString)) 243 if (/^re:+/.test(searchString))
149 domain = domain.replace(new RegExp(RegExp.rightContext, "g"), replacement) ; 244 domain = domain.replace(new RegExp(RegExp.rightContext, "g"), replacement) ;
150 else 245 else
151 domain = domain.replace(searchString, replacement); 246 domain = domain.replace(searchString, replacement);
152 } 247 }
153
154 // Apply user's whitelist
155 let whitelist = Prefs.whitelist;
156 if (whitelist.hasOwnProperty(domain) || /^www\./.test(domain) && whitelist.has OwnProperty(domain.substr(4)))
157 {
158 return domain;
159 }
160 248
161 // Now apply our rules on the domain name 249 // Now apply our rules on the domain name
162 for (let i = 0, l = rules.expressions.length; i < l; i++) 250 for (let i = 0, l = rules.expressions.length; i < l; i++)
163 domain = applyExpression(domain, rules.expressions[i]); 251 domain = applyExpression(domain, rules.expressions[i]);
164 252
165 // Find similar known domains, test domains without the www. prefix 253 // Find similar known domains, test domains without the www. prefix
166 if (domain.substr(0, 4) == "www.") 254 if (domain.substr(0, 4) == "www.")
167 domain = "www." + getBestMatch(domain.substr(4), rules.domain, 1, "."); 255 domain = "www." + getBestMatch(domain.substr(4), rules.domain, 1, ".");
168 else 256 else
169 domain = getBestMatch(domain, rules.domain, 1, "."); 257 domain = getBestMatch(domain, rules.domain, 1, ".");
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 bestSuggestionDistance = distance; 400 bestSuggestionDistance = distance;
313 bestSuggestionMatched = matchedLen; 401 bestSuggestionMatched = matchedLen;
314 bestSuggestionPriority = priority; 402 bestSuggestionPriority = priority;
315 } 403 }
316 } 404 }
317 if (bestSuggestion) 405 if (bestSuggestion)
318 return input.substr(0, input.length - bestSuggestionMatched) + bestSuggestio n; 406 return input.substr(0, input.length - bestSuggestionMatched) + bestSuggestio n;
319 else 407 else
320 return input; 408 return input;
321 } 409 }
OLDNEW

Powered by Google App Engine
This is Rietveld