Skip to content
This repository was archived by the owner on Nov 15, 2017. It is now read-only.

Commit 83e213c

Browse files
committed
this brings coverage to 99%
1 parent 3bc0599 commit 83e213c

File tree

1 file changed

+131
-58
lines changed

1 file changed

+131
-58
lines changed

js/abp-hide-filters.js

Lines changed: 131 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ FilterPlainMore.prototype.retrieve = function(s, out) {
107107

108108
/******************************************************************************/
109109

110+
// HTML tag specific to a hostname
111+
// Examples:
112+
// lindaikeji.blogspot.com##a > img[height="600"]
113+
// japantimes.co.jp##table[align="right"][width="250"]
114+
115+
var FilterElementHostname = function(s, hostname) {
116+
this.s = s;
117+
this.hostname = hostname;
118+
};
119+
120+
FilterElementHostname.prototype.retrieve = function(s, out) {
121+
if ( pageHostname.slice(-this.hostname.length) === this.hostname ) {
122+
out.push(this.s);
123+
}
124+
};
125+
126+
/******************************************************************************/
127+
110128
// Pure id- and class-based filters specific to a hostname
111129
// Examples:
112130
// search.snapdo.com###ABottomD
@@ -164,25 +182,30 @@ FilterBucket.prototype.retrieve = function(s, out) {
164182
/******************************************************************************/
165183

166184
var FilterParser = function() {
167-
this.f = '';
185+
this.s = '';
186+
this.prefix = '';
187+
this.suffix = '';
168188
this.anchor = 0;
169189
this.filterType = '#';
170190
this.hostnames = [];
171191
this.invalid = false;
172192
this.unsupported = false;
193+
this.reParser = /^\s*([^#]*)(#[#@])(.+)\s*$/;
173194
this.rePlain = /^([#.][\w-]+)/;
174195
this.rePlainMore = /^[#.][\w-]+[^\w-]/;
196+
this.reElement = /^[a-z]/i;
175197
};
176198

177199
/******************************************************************************/
178200

179201
FilterParser.prototype.reset = function() {
180-
this.f = '';
181-
this.anchor = 0;
202+
this.s = '';
203+
this.prefix = '';
204+
this.suffix = '';
205+
this.anchor = '';
182206
this.filterType = '#';
183207
this.hostnames = [];
184208
this.invalid = false;
185-
this.unsupported = false;
186209
return this;
187210
};
188211

@@ -192,45 +215,41 @@ FilterParser.prototype.parse = function(s) {
192215
// important!
193216
this.reset();
194217

195-
this.anchor = s.indexOf('##');
196-
if ( this.anchor < 0 ) {
197-
this.anchor = s.indexOf('#@#');
198-
if ( this.anchor < 0 ) {
199-
this.invalid = true;
200-
return this;
201-
}
202-
}
203-
this.filterType = s.charAt(this.anchor + 1);
204-
if ( this.anchor > 0 ) {
205-
this.hostnames = s.slice(0, this.anchor).split(/\s*,\s*/);
206-
}
207-
if ( this.filterType === '@' ) {
208-
this.f = s.slice(this.anchor + 3);
209-
} else {
210-
this.f = s.slice(this.anchor + 2);
211-
}
212-
213-
// selector
214-
var selectorType = this.f.charAt(0);
215-
if ( selectorType === '#' || selectorType === '.' ) {
218+
var matches = this.reParser.exec(s);
219+
if ( matches === null || matches.length !== 4 ) {
220+
this.invalid = true;
216221
return this;
217222
}
218223

219-
this.unspported = true;
224+
// Remember original string
225+
this.s = s;
226+
this.prefix = matches[1];
227+
this.anchor = matches[2];
228+
this.suffix = matches[3];
220229

230+
this.filterType = this.anchor.charAt(1);
231+
if ( this.prefix !== '' ) {
232+
this.hostnames = this.prefix.split(/\s*,\s*/);
233+
}
221234
return this;
222235
};
223236

224237
/******************************************************************************/
225238

226239
FilterParser.prototype.isPlainMore = function() {
227-
return this.rePlainMore.test(this.f);
240+
return this.rePlainMore.test(this.suffix);
241+
};
242+
243+
/******************************************************************************/
244+
245+
FilterParser.prototype.isElement = function() {
246+
return this.reElement.test(this.suffix);
228247
};
229248

230249
/******************************************************************************/
231250

232251
FilterParser.prototype.extractPlain = function() {
233-
var matches = this.rePlain.exec(this.f);
252+
var matches = this.rePlain.exec(this.suffix);
234253
if ( matches && matches.length === 2 ) {
235254
return matches[1];
236255
}
@@ -242,7 +261,7 @@ FilterParser.prototype.extractPlain = function() {
242261
var FilterContainer = function() {
243262
this.filterParser = new FilterParser();
244263
this.acceptedCount = 0;
245-
this.rejectedCount = 0;
264+
this.processedCount = 0;
246265
this.filters = {};
247266
};
248267

@@ -252,55 +271,71 @@ var FilterContainer = function() {
252271

253272
FilterContainer.prototype.reset = function() {
254273
this.acceptedCount = 0;
255-
this.rejectedCount = 0;
274+
this.processedCount = 0;
256275
this.filters = {};
257276
};
258277

259278
/******************************************************************************/
260279

261280
FilterContainer.prototype.add = function(s) {
262281
var parsed = this.filterParser.parse(s);
282+
if ( parsed.invalid ) {
283+
return false;
284+
}
285+
286+
this.processedCount += 1;
263287

264288
//if ( s === 'mail.google.com##.nH.adC > .nH > .nH > .u5 > .azN' ) {
265289
// debugger;
266290
//}
267291

268-
if ( parsed.invalid ) {
269-
return false;
270-
}
271-
272-
var selectorType = parsed.f.charAt(0);
292+
var selectorType = parsed.suffix.charAt(0);
273293
if ( selectorType === '#' || selectorType === '.' ) {
274-
this.acceptedCount += 1;
275294
return this.addPlainFilter(parsed);
276295
}
277296

278-
this.rejectedCount += 1;
297+
if ( parsed.isElement() ) {
298+
return this.addElementFilter(parsed);
299+
}
300+
279301
return false;
280302
};
281303

282304
/******************************************************************************/
283305

284306
FilterContainer.prototype.freeze = function() {
285307
console.log('HTTPSB> adp-hide-filters.js: %d filters accepted', this.acceptedCount);
286-
console.log('HTTPSB> adp-hide-filters.js: %d filters rejected', this.rejectedCount);
287-
console.log('HTTPSB> adp-hide-filters.js: coverage is %s%', (this.acceptedCount * 100 / (this.acceptedCount+this.rejectedCount)).toFixed(1));
308+
console.log('HTTPSB> adp-hide-filters.js: %d filters processed', this.processedCount);
309+
console.log('HTTPSB> adp-hide-filters.js: coverage is %s%', (this.acceptedCount * 100 / this.processedCount).toFixed(1));
288310

289311
// histogram('allFilters', this.filters);
290312
};
291313

292314
/******************************************************************************/
293315

316+
// TSSSDD
317+
// | | |
318+
// | | |
319+
// | | +---- domain (can be nil)
320+
// | +---- suffix (can be bil)
321+
// +---- type (# or @)
322+
294323
FilterContainer.prototype.makeHash = function(filterType, selector, domain) {
295-
var i = (selector.length - 1) >> 2;
296-
var hash = String.fromCharCode(
297-
filterType.charCodeAt(0) << 8 |
298-
selector.charCodeAt(0),
299-
(selector.charCodeAt(1) & 0xF) << 12 |
300-
(selector.charCodeAt(1+i) & 0xF) << 8 |
301-
(selector.charCodeAt(1+i+i) & 0xF) << 4 |
302-
(selector.charCodeAt(1+i+i+i) & 0xF)
303-
);
324+
var i;
325+
var hash;
326+
327+
if ( selector === '') {
328+
hash = String.fromCharCode(filterType.charCodeAt(0) << 8);
329+
} else {
330+
i = (selector.length - 1) >> 2;
331+
hash = String.fromCharCode(
332+
filterType.charCodeAt(0) << 8 | selector.charCodeAt(0),
333+
(selector.charCodeAt(1) & 0xF) << 12 |
334+
(selector.charCodeAt(1+i) & 0xF) << 8 |
335+
(selector.charCodeAt(1+i+i) & 0xF) << 4 |
336+
(selector.charCodeAt(1+i+i+i) & 0xF)
337+
);
338+
}
304339
if ( !domain ) {
305340
return hash;
306341
}
@@ -323,9 +358,10 @@ FilterContainer.prototype.addPlainFilter = function(parsed) {
323358
if ( parsed.hostnames.length ) {
324359
return this.addPlainHostnameFilter(parsed);
325360
}
326-
var f = new FilterPlain(parsed.f);
327-
var hash = this.makeHash(parsed.filterType, parsed.f);
361+
var f = new FilterPlain(parsed.suffix);
362+
var hash = this.makeHash(parsed.filterType, parsed.suffix);
328363
this.addFilterEntry(hash, f);
364+
this.acceptedCount += 1;
329365
};
330366

331367
/******************************************************************************/
@@ -334,17 +370,17 @@ FilterContainer.prototype.addPlainHostnameFilter = function(parsed) {
334370
var httpsburi = HTTPSB.URI;
335371
var f, hash;
336372
var hostnames = parsed.hostnames;
337-
var i = hostnames.length;
338-
var hostname;
373+
var i = hostnames.length, hostname;
339374
while ( i-- ) {
340375
hostname = hostnames[i];
341376
if ( !hostname ) {
342377
continue;
343378
}
344-
f = new FilterPlainHostname(parsed.f, hostname);
345-
hash = this.makeHash(parsed.filterType, parsed.f, httpsburi.domainFromHostname(hostname));
379+
f = new FilterPlainHostname(parsed.suffix, hostname);
380+
hash = this.makeHash(parsed.filterType, parsed.suffix, httpsburi.domainFromHostname(hostname));
346381
this.addFilterEntry(hash, f);
347382
}
383+
this.acceptedCount += 1;
348384
};
349385

350386
/******************************************************************************/
@@ -357,9 +393,10 @@ FilterContainer.prototype.addPlainMoreFilter = function(parsed) {
357393
if ( plainSelector === '' ) {
358394
return;
359395
}
360-
var f = new FilterPlainMore(parsed.f);
396+
var f = new FilterPlainMore(parsed.suffix);
361397
var hash = this.makeHash(parsed.filterType, plainSelector);
362398
this.addFilterEntry(hash, f);
399+
this.acceptedCount += 1;
363400
};
364401

365402
/******************************************************************************/
@@ -372,17 +409,44 @@ FilterContainer.prototype.addPlainMoreHostnameFilter = function(parsed) {
372409
var httpsburi = HTTPSB.URI;
373410
var f, hash;
374411
var hostnames = parsed.hostnames;
375-
var i = hostnames.length;
376-
var hostname;
412+
var i = hostnames.length, hostname;
377413
while ( i-- ) {
378414
hostname = hostnames[i];
379415
if ( !hostname ) {
380416
continue;
381417
}
382-
f = new FilterPlainMoreHostname(parsed.f, hostname);
418+
f = new FilterPlainMoreHostname(parsed.suffix, hostname);
383419
hash = this.makeHash(parsed.filterType, plainSelector, httpsburi.domainFromHostname(hostname));
384420
this.addFilterEntry(hash, f);
385421
}
422+
this.acceptedCount += 1;
423+
};
424+
425+
/******************************************************************************/
426+
427+
FilterContainer.prototype.addElementFilter = function(parsed) {
428+
if ( parsed.hostnames.length ) {
429+
return this.addElementHostnameFilter(parsed);
430+
}
431+
};
432+
433+
/******************************************************************************/
434+
435+
FilterContainer.prototype.addElementHostnameFilter = function(parsed) {
436+
var httpsburi = HTTPSB.URI;
437+
var f, hash;
438+
var hostnames = parsed.hostnames;
439+
var i = hostnames.length, hostname;
440+
while ( i-- ) {
441+
hostname = hostnames[i];
442+
if ( !hostname ) {
443+
continue;
444+
}
445+
f = new FilterElementHostname(parsed.suffix, hostname);
446+
hash = this.makeHash(parsed.filterType, '', httpsburi.domainFromHostname(hostname));
447+
this.addFilterEntry(hash, f);
448+
}
449+
this.acceptedCount += 1;
386450
};
387451

388452
/******************************************************************************/
@@ -428,6 +492,15 @@ FilterContainer.prototype.retrieve = function(url, inSelectors) {
428492
bucket.retrieve(selector, donthideSelectors);
429493
}
430494
}
495+
// Generic elements for a specific domain
496+
hash = this.makeHash('#', '', domain);
497+
if ( bucket = this.filters[hash] ) {
498+
bucket.retrieve(selector, hideSelectors);
499+
}
500+
hash = this.makeHash('@', '', domain);
501+
if ( bucket = this.filters[hash] ) {
502+
bucket.retrieve(selector, donthideSelectors);
503+
}
431504
return {
432505
hide: hideSelectors.join(','),
433506
donthide: donthideSelectors.join(',')

0 commit comments

Comments
 (0)