@@ -67,7 +67,7 @@ var histogram = function(label, buckets) {
6767 h = h.slice(0, 50);
6868
6969 h.forEach(function(v) {
70- console.log('\tkey=%s count=%d', v.k, v.n);
70+ console.log('\tkey="%s" count=%d', v.k, v.n);
7171 });
7272 console.log('\tTotal buckets count: %d', total);
7373};
@@ -206,7 +206,7 @@ FilterParser.prototype.parse = function(s) {
206206
207207 // 2014-05-23:
208208 // https://github.com/gorhill/httpswitchboard/issues/260
209- // Any sequence of `#` longer than two means the line is not a valid
209+ // Any sequence of `#` longer than one means the line is not a valid
210210 // cosmetic filter.
211211 if ( this . suffix . indexOf ( '##' ) >= 0 ) {
212212 this . invalid = true ;
@@ -343,7 +343,7 @@ FilterContainer.prototype.freeze = function() {
343343 //console.log('HTTPSB> adp-hide-filters.js: unfiltered dont hide selectors:', this.donthideUnfiltered);
344344 //console.log('HTTPSB> adp-hide-filters.js: rejected selectors:', this.rejected);
345345
346- //histogram('allFilters', this.filters);
346+ // histogram('allFilters', this.filters);
347347} ;
348348
349349/******************************************************************************/
@@ -363,99 +363,133 @@ FilterContainer.prototype.freeze = function() {
363363// |
364364// +-- filter type ('#'=hide '@'=unhide)
365365//
366- // TODO: Keep trying to find a better hash (ls 12 bits of FNV32a?).
367- // Ideally, all buckets have the same (low) number of filters.
368366
369367var makePrefixHash = function ( type , prefix ) {
368+ // Ref: Given a URL, returns a unique 4-character long hash string
369+ // Based on: FNV32a
370+ // http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-reference-source
371+ // The rest is custom, suited for HTTPSB.
370372 var len = prefix . length ;
371373 var i2 = len >> 1 ;
372374 var i4 = len >> 2 ;
373375 var i8 = len >> 3 ;
374- var pCode = ( prefix . charCodeAt ( 0 ) & 3 ) << 14 | // 0/8
375- ( prefix . charCodeAt ( i8 ) & 3 ) << 12 | // 1/8
376- ( prefix . charCodeAt ( i4 ) & 3 ) << 10 | // 2/8
377- ( prefix . charCodeAt ( i4 + i8 ) & 3 ) << 8 | // 3/8
378- ( prefix . charCodeAt ( i2 ) & 3 ) << 6 | // 4/8
379- ( prefix . charCodeAt ( i2 + i8 ) & 3 ) << 4 | // 5/8
380- ( prefix . charCodeAt ( i2 + i4 ) & 3 ) << 2 | // 6/8
381- ( prefix . charCodeAt ( len - 1 ) & 3 ) ; // 8/8
382- return String . fromCharCode ( type . charCodeAt ( 0 ) , pCode , 0 ) ;
376+ var hint = ( 0x811c9dc5 ^ prefix . charCodeAt ( 0 ) ) >>> 0 ;
377+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
378+ hint >>>= 0 ;
379+ hint ^= prefix . charCodeAt ( i8 ) ;
380+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
381+ hint >>>= 0 ;
382+ hint ^= prefix . charCodeAt ( i4 ) ;
383+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
384+ hint >>>= 0 ;
385+ hint ^= prefix . charCodeAt ( i4 + i8 ) ;
386+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
387+ hint >>>= 0 ;
388+ hint ^= prefix . charCodeAt ( i2 ) ;
389+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
390+ hint >>>= 0 ;
391+ hint ^= prefix . charCodeAt ( i2 + i8 ) ;
392+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
393+ hint >>>= 0 ;
394+ hint ^= prefix . charCodeAt ( i2 + i4 ) ;
395+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
396+ hint >>>= 0 ;
397+ hint ^= prefix . charCodeAt ( len - 1 ) ;
398+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
399+ hint >>>= 0 ;
400+ return String . fromCharCode ( type . charCodeAt ( 0 ) , hint & 0xFFFF , 0 ) ;
383401} ;
384402
385403var makeSuffixHash = function ( type , suffix ) {
386404 var len = suffix . length ;
387405 var i2 = len >> 1 ;
388406 var i4 = len >> 2 ;
389407 var i8 = len >> 3 ;
390- var sCode = ( suffix . charCodeAt ( 0 ) & 3 ) << 14 | // 0/8
391- ( suffix . charCodeAt ( i8 ) & 3 ) << 12 | // 1/8
392- ( suffix . charCodeAt ( i4 ) & 3 ) << 10 | // 2/8
393- ( suffix . charCodeAt ( i4 + i8 ) & 3 ) << 8 | // 3/8
394- ( suffix . charCodeAt ( i2 ) & 3 ) << 6 | // 4/8
395- ( suffix . charCodeAt ( i2 + i8 ) & 3 ) << 4 | // 5/8
396- ( suffix . charCodeAt ( i2 + i4 ) & 3 ) << 2 | // 6/8
397- ( suffix . charCodeAt ( len - 1 ) & 3 ) ; // 8/8
398- return String . fromCharCode ( type . charCodeAt ( 0 ) , 0 , sCode ) ;
408+ var hint = ( 0x811c9dc5 ^ suffix . charCodeAt ( 0 ) ) >>> 0 ;
409+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
410+ hint >>>= 0 ;
411+ hint ^= suffix . charCodeAt ( i8 ) ;
412+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
413+ hint >>>= 0 ;
414+ hint ^= suffix . charCodeAt ( i4 ) ;
415+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
416+ hint >>>= 0 ;
417+ hint ^= suffix . charCodeAt ( i4 + i8 ) ;
418+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
419+ hint >>>= 0 ;
420+ hint ^= suffix . charCodeAt ( i2 ) ;
421+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
422+ hint >>>= 0 ;
423+ hint ^= suffix . charCodeAt ( i2 + i8 ) ;
424+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
425+ hint >>>= 0 ;
426+ hint ^= suffix . charCodeAt ( i2 + i4 ) ;
427+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
428+ hint >>>= 0 ;
429+ hint ^= suffix . charCodeAt ( len - 1 ) ;
430+ hint += ( hint << 1 ) + ( hint << 4 ) + ( hint << 7 ) + ( hint << 8 ) + ( hint << 24 ) ;
431+ hint >>>= 0 ;
432+ return String . fromCharCode ( type . charCodeAt ( 0 ) , 0 , hint & 0x0FFF ) ;
399433} ;
400434
401435/**
402436Histogram for above hash generator:
403437
404438Histogram allFilters
405- Entries with only 3 filter(s) start at index 1869 (key = "#镉 ")
406- Entries with only 2 filter(s) start at index 3117 (key = "@ᶹ ")
407- Entries with only 1 filter(s) start at index 5902 (key = "#蹐 ")
408- key=#叭 count=141
409- key=#徭 count=101
410- key=#雽 count=59
411- key=#ュ count=49
412- key=#֭ count=47
413- key=#節 count=42
414- key=#㼉 count=36
415- key=#傭 count=36
416- key=# count=35
417- key=#ᆳ count=32
418- key=#教 count=32
419- key=#ꗴ count=29
420- key=#홹 count=29
421- key=#敨 count=27
422- key=#䓕 count=27
423- key=#媭 count=27
424- key=#㪉 count=26
425- key=#ꪭ count=25
426- key=#釭 count=24
427- key=#� count=24
428- key=#ꕔ count=24
429- key=#嵩 count=24
430- key=#錀 count=23
431- key=#ꗰ count=22
432- key=#酹 count=22
433- key=#ꖭ count=22
434- key=# count=22
435- key=#꿴 count=21
436- key=#ㅩ count=21
437- key=#龭 count=21
438- key=#施 count=21
439- key=#ꂭ count=20
440- key=#ꔄ count=20
441- key=#� count=19
442- key=#ય count=19
443- key=#꽔 count=19
444- key=#ꗼ count=19
445- key=#鎀 count=19
446- key=#ꕘ count=19
447- key=#隹 count=19
448- key=# count=19
449- key=#璙 count=18
450- key=# count=18
451- key=#֯ count=18
452- key=# count=18
453- key=#䉏 count=17
454- key=#ꔌ count=17
455- key=# count=17
456- key=#嫜 count=17
457- key=#ᱭ count=17
458- Total buckets count: 14348
439+ Entries with only 3 filter(s) start at index 2706 (key = "#ꍵ ")
440+ Entries with only 2 filter(s) start at index 4349 (key = "#냶 ")
441+ Entries with only 1 filter(s) start at index 6896 (key = "#퀛 ")
442+ key="#싣" count=141
443+ key="#隁" count=57
444+ key="#Ꚇ" count=48
445+ key="#" count=45
446+ key="#캃" count=36
447+ key="#력" count=33
448+ key="#끻" count=30
449+ key="#u" count=26
450+ key="#" count=25
451+ key="#Ꮳ" count=24
452+ key="#鵲" count=23
453+ key="#䙇" count=20
454+ key="#ḇ" count=19
455+ key="#睅" count=19
456+ key="#㔽" count=19
457+ key="#뻧" count=18
458+ key="#䕀" count=18
459+ key="#퉫" count=17
460+ key="#筙" count=17
461+ key="#㮰" count=17
462+ key="#鯛" count=16
463+ key="#" count=16
464+ key="#꣱" count=16
465+ key="#ü" count=16
466+ key="#告" count=16
467+ key="#╡" count=16
468+ key="#㰁" count=16
469+ key="#৹" count=16
470+ key="#镳" count=15
471+ key="#碇" count=15
472+ key="#৾" count=15
473+ key="#貿" count=15
474+ key="#š" count=15
475+ key="#" count=15
476+ key="#" count=14
477+ key="#ຏ" count=14
478+ key="#낶" count=14
479+ key="#瑻" count=14
480+ key="#ৡ" count=14
481+ key="#" count=13
482+ key="#ᯋ" count=13
483+ key="#⼒" count=13
484+ key="#腫" count=13
485+ key="#겚" count=13
486+ key="#耏" count=13
487+ key="#匋" count=13
488+ key="#튦" count=13
489+ key="#ﰹ" count=13
490+ key="#㭴" count=13
491+ key="#" count=13
492+ Total buckets count: 12098
459493*/
460494
461495/******************************************************************************/
@@ -520,49 +554,70 @@ FilterContainer.prototype.addFilterEntry = function(hash, f) {
520554
521555/******************************************************************************/
522556
523- FilterContainer . prototype . retrieve = function ( url , inSelectors ) {
524- if ( httpsb . userSettings . parseAllABPHideFilters !== true ||
525- httpsb . getTemporaryABPFilteringFromPageURL ( url ) !== true ) {
557+ FilterContainer . prototype . retrieve = function ( request ) {
558+ if ( httpsb . userSettings . parseAllABPHideFilters !== true ) {
526559 return ;
527560 }
561+
562+ if ( httpsb . getTemporaryABPFilteringFromPageURL ( request . pageURL ) !== true ) {
563+ return ;
564+ }
565+
566+ //quickProfiler.start('FilterContainer.retrieve()');
567+
528568 //filterTestCount = 0;
529569 //bucketTestCount = 0;
530- var hostname = pageHostname = httpsb . URI . hostnameFromURI ( url ) ;
531- var domain = httpsb . URI . domainFromHostname ( hostname ) ;
532- var hideSelectors = [ ] ;
533- var donthideSelectors = [ ] ;
534- var i = inSelectors . length ;
535- var selector , hash , bucket ;
536- while ( i -- ) {
537- selector = inSelectors [ i ] ;
538- if ( ! selector ) {
539- continue ;
570+
571+ var r = {
572+ hide : [ ] ,
573+ donthide : [ ] ,
574+ hideUnfiltered : [ ] ,
575+ donthideUnfiltered : [ ]
576+ } ;
577+
578+ var hash , bucket ;
579+
580+ if ( request . locationURL ) {
581+ var hostname = pageHostname = httpsb . URI . hostnameFromURI ( request . locationURL ) ;
582+ var domain = httpsb . URI . domainFromHostname ( hostname ) ;
583+ hash = makePrefixHash ( '#' , domain ) ;
584+ if ( bucket = this . filters [ hash ] ) {
585+ //bucketTestCount += 1;
586+ //filterTestCount += 1;
587+ bucket . retrieve ( null , r . hide ) ;
540588 }
541- hash = makeSuffixHash ( '# ', selector ) ;
589+ hash = makePrefixHash ( '@ ', domain ) ;
542590 if ( bucket = this . filters [ hash ] ) {
543591 //bucketTestCount += 1;
544592 //filterTestCount += 1;
545- bucket . retrieve ( selector , hideSelectors ) ;
593+ bucket . retrieve ( null , r . donthide ) ;
546594 }
547595 }
548- // Any selectors for a specific domain
549- // rhill 2014-05-20: When a domain exists, the set of selectors is
550- // already quite narrowed down, so no need to actually narrow further
551- // based on selector type -- this probably save a good chunk of overhead
552- // in the above loop.
553- hash = makePrefixHash ( '#' , domain ) ;
554- if ( bucket = this . filters [ hash ] ) {
555- //bucketTestCount += 1;
556- //filterTestCount += 1;
557- bucket . retrieve ( selector , hideSelectors ) ;
558- }
559- hash = makePrefixHash ( '@' , domain ) ;
560- if ( bucket = this . filters [ hash ] ) {
561- //bucketTestCount += 1;
562- //filterTestCount += 1;
563- bucket . retrieve ( selector , donthideSelectors ) ;
596+
597+ if ( request . selectors ) {
598+ var hideSelectors = r . hide ;
599+ var selectors = request . selectors ;
600+ var i = selectors . length ;
601+ var selector ;
602+ while ( i -- ) {
603+ selector = selectors [ i ] ;
604+ if ( ! selector ) {
605+ continue ;
606+ }
607+ hash = makeSuffixHash ( '#' , selector ) ;
608+ if ( bucket = this . filters [ hash ] ) {
609+ //bucketTestCount += 1;
610+ //filterTestCount += 1;
611+ bucket . retrieve ( selector , hideSelectors ) ;
612+ }
613+ }
614+
615+ r . hideUnfiltered = this . hideUnfiltered ;
616+ r . donthideUnfiltered = this . donthideUnfiltered ;
564617 }
565618
619+ //quickProfiler.stop();
620+
566621/*
567622 console.log(
568623 'HTTPSB> abp-hide-filters.js: "%s"\n\t%d selectors in => %d/%d filters/buckets tested => %d selectors out',
@@ -574,12 +629,7 @@ FilterContainer.prototype.retrieve = function(url, inSelectors) {
574629 );
575630*/
576631
577- return {
578- hide : hideSelectors ,
579- donthide : donthideSelectors ,
580- hideUnfiltered : this . hideUnfiltered ,
581- donthideUnfiltered : this . donthideUnfiltered
582- } ;
632+ return r ;
583633} ;
584634
585635/******************************************************************************/
0 commit comments