|
21 | 21 |
|
22 | 22 | /******************************************************************************/ |
23 | 23 |
|
24 | | -// unpacked: |
25 | | -// map[hostname] = true/false |
26 | | -// packed |
27 | | -// map[tld].[leftover.length] = haystack on which to perform binary search |
28 | | -// |
29 | | -// Idea for mapping according to length inspired from reading the section |
30 | | -// "String-based Binary Search" @ http://ejohn.org/blog/revised-javascript-dictionary-search/ |
31 | | -// Except for the core binary search I reused my own faithful version which has |
32 | | -// served me well over time. |
33 | | -// |
34 | | -// Figuratively speaking, this means when looking up a hostname, aka the needle, |
35 | | -// the TLD of the hostname tells us on which farm we must go, and the length |
36 | | -// of the hostname minus TLD tells us which haystack on that farm with must |
37 | | -// look into. |
38 | | -// |
39 | | -// Before, with quickIndexOf(), I was binary-searching one big ass haystack, |
40 | | -// now, using very easy to compute hostname patterns, I lookup a smaller |
41 | | -// haystack before binary-searching. But I appreciate especially the reduced |
42 | | -// memory footprint -- through the removal of all redundant information within |
43 | | -// a single haystack. |
44 | | -// |
45 | | -// Stats: |
46 | | -// Using Object for farm: sizeof(blacklistReadonly): 1,050,028 |
47 | | -// Using Array for farm: sizeof(blacklistReadonly): 1,050,640 |
48 | | -// So I will stick to using an Array because: |
49 | | -// http://jsperf.com/performance-of-array-vs-object/49 |
50 | | - |
51 | | -var blacklistReadonly = { |
52 | | - packed: {}, |
53 | | - unpacked: null, |
54 | | - |
55 | | - unpack: function() { |
56 | | - var unpacked = this.unpacked; |
57 | | - if ( unpacked ) { |
58 | | - return unpacked; |
59 | | - } |
60 | | - unpacked = {}; |
61 | | - this._unpack(unpacked, ''); |
62 | | - this.packed = null; |
63 | | - this.unpacked = unpacked; |
64 | | - return unpacked; |
65 | | - }, |
66 | | - |
67 | | - pack: function() { |
68 | | - var packed = this.packed; |
69 | | - if ( packed ) { |
70 | | - return packed; |
71 | | - } |
72 | | - packed = {}; |
73 | | - var unpacked = this.unpacked; |
74 | | - var hostnames = Object.keys(unpacked); |
75 | | - var iHostname = hostnames.length; |
76 | | - var hostname, idot, tld, hnPrefix; |
77 | | - var len, farm, haystack; |
78 | | - while ( iHostname-- ) { |
79 | | - hostname = hostnames[iHostname]; |
80 | | - idot = hostname.lastIndexOf('.'); |
81 | | - hnPrefix = hostname.slice(0, idot); |
82 | | - tld = hostname.slice(idot+1); |
83 | | - len = hnPrefix.length; |
84 | | - if ( !packed[tld] ) { |
85 | | - packed[tld] = []; |
86 | | - } |
87 | | - farm = packed[tld]; |
88 | | - if ( !farm[len] ) { |
89 | | - farm[len] = {}; |
90 | | - } |
91 | | - haystack = farm[len]; |
92 | | - haystack[hnPrefix] = true; |
93 | | - } |
94 | | - var tldKeys = Object.keys(packed); |
95 | | - var iTld = tldKeys.length; |
96 | | - while ( iTld-- ) { |
97 | | - tld = tldKeys[iTld]; |
98 | | - farm = packed[tld]; |
99 | | - len = farm.length; |
100 | | - while ( len-- ) { |
101 | | - if ( farm[len] !== undefined ) { |
102 | | - farm[len] = Object.keys(farm[len]).sort().join(''); |
103 | | - } |
104 | | - } |
105 | | - } |
106 | | - this.unpacked = null; |
107 | | - this.packed = packed; |
108 | | - return packed; |
109 | | - }, |
110 | | - |
111 | | - toFilters: function(des) { |
112 | | - var unpacked = this.unpacked; |
113 | | - if ( unpacked ) { |
114 | | - var hostnames = Object.keys(unpacked); |
115 | | - var i = hostnames.length; |
116 | | - while ( i-- ) { |
117 | | - des['*/' + hostnames[i]] = true; |
118 | | - } |
119 | | - return; |
120 | | - } |
121 | | - this._unpack(des, '*/'); |
122 | | - }, |
123 | | - |
124 | | - addOne: function(hostname) { |
125 | | - var unpacked = this.unpacked || this.unpack(); |
126 | | - unpacked[hostname] = true; |
127 | | - }, |
128 | | - |
129 | | - addMany: function(s) { |
130 | | - var unpacked = this.unpacked || this.unpack(); |
131 | | - var hostnames = s.split(/\s+/); |
132 | | - var i = hostnames.length; |
133 | | - var hostname; |
134 | | - while ( i-- ) { |
135 | | - hostname = hostnames[i]; |
136 | | - if ( hostname.length ) { |
137 | | - unpacked[hostname.toLowerCase()] = true; |
138 | | - } |
139 | | - } |
140 | | - }, |
141 | | - |
142 | | - find: function(hostname) { |
143 | | - var packed = this.packed || this.pack(); |
144 | | - var idot = hostname.lastIndexOf('.'); |
145 | | - var tld = hostname.slice(idot+1); |
146 | | - var farm = packed[tld]; |
147 | | - if ( !farm ) { |
148 | | - return false; |
149 | | - } |
150 | | - var hnPrefix = hostname.slice(0, idot); |
151 | | - var len = hnPrefix.length; |
152 | | - var haystack = farm[len]; |
153 | | - if ( !haystack ) { |
154 | | - return false; |
155 | | - } |
156 | | - var left = 0; |
157 | | - var right = Math.round(haystack.length / len); |
158 | | - var i, needle; |
159 | | - while ( left < right ) { |
160 | | - i = left + right >> 1; |
161 | | - needle = haystack.substr(i * len, len); |
162 | | - if ( hnPrefix < needle ) { |
163 | | - right = i; |
164 | | - } else if ( hnPrefix > needle ) { |
165 | | - left = i + 1; |
166 | | - } else { |
167 | | - return true; |
168 | | - } |
169 | | - } |
170 | | - return false; |
171 | | - }, |
172 | | - |
173 | | - // this exists only in order to avoid code duplication |
174 | | - _unpack: function(des, prefix) { |
175 | | - var packed = this.packed; |
176 | | - var tlds = Object.keys(packed); |
177 | | - var iTld = tlds.length; |
178 | | - var tld, farm, len; |
179 | | - var haystack, iStraw; |
180 | | - while ( iTld-- ) { |
181 | | - tld = tlds[iTld]; |
182 | | - farm = packed[tld]; |
183 | | - len = farm.length; |
184 | | - while ( len-- ) { |
185 | | - haystack = farm[len]; |
186 | | - if ( haystack ) { |
187 | | - iStraw = haystack.length; |
188 | | - while ( iStraw ) { |
189 | | - iStraw -= len; |
190 | | - des[prefix + haystack.substr(iStraw, len) + '.' + tld] = true; |
191 | | - } |
192 | | - } |
193 | | - } |
194 | | - } |
195 | | - } |
196 | | -}; |
197 | | - |
198 | | -/******************************************************************************/ |
199 | | - |
200 | 24 | var HTTPSB = { |
201 | 25 | manifest: chrome.runtime.getManifest(), |
202 | 26 |
|
@@ -244,14 +68,14 @@ var HTTPSB = { |
244 | 68 | // effective lists |
245 | 69 | whitelist: { }, |
246 | 70 | blacklist: { '*/*': true }, |
247 | | - graylist: { }, // this will override preset blacklists |
| 71 | + graylist: { }, |
248 | 72 | // user lists |
249 | 73 | whitelistUser: {}, |
250 | 74 | blacklistUser: {}, |
251 | 75 | graylistUser: {}, // this will override preset blacklists |
252 | 76 |
|
253 | 77 | // Current entries from remote blacklists |
254 | | - blacklistReadonly: blacklistReadonly, |
| 78 | + blacklistReadonly: {}, |
255 | 79 |
|
256 | 80 | // https://github.com/gorhill/httpswitchboard/issues/19 |
257 | 81 | excludeRegex: /^https?:\/\/chrome\.google\.com\/(extensions|webstore)/, |
|
0 commit comments