@@ -29,6 +29,8 @@ const StaticExtFilteringHostnameDB = class {
29
29
this.timer = undefined;
30
30
this.strToIdMap = new Map();
31
31
this.hostnameToSlotIdMap = new Map();
32
+
this.regexToSlotIdMap = new Map();
33
+
this.regexMap = new Map();
32
34
// Array of integer pairs
33
35
this.hostnameSlots = [];
34
36
// Array of strings (selectors and pseudo-selectors)
@@ -51,9 +53,16 @@ const StaticExtFilteringHostnameDB = class {
51
53
}
52
54
}
53
55
const strId = iStr << this.nBits | bits;
54
-
let iHn = this.hostnameToSlotIdMap.get(hn);
56
+
const hnIsNotRegex = hn.charCodeAt(0) !== 0x2F /* / */;
57
+
let iHn = hnIsNotRegex
58
+
? this.hostnameToSlotIdMap.get(hn)
59
+
: this.regexToSlotIdMap.get(hn);
55
60
if ( iHn === undefined ) {
56
-
this.hostnameToSlotIdMap.set(hn, this.hostnameSlots.length);
61
+
if ( hnIsNotRegex ) {
62
+
this.hostnameToSlotIdMap.set(hn, this.hostnameSlots.length);
63
+
} else {
64
+
this.regexToSlotIdMap.set(hn, this.hostnameSlots.length);
65
+
}
57
66
this.hostnameSlots.push(strId, 0);
58
67
return;
59
68
}
@@ -67,9 +76,11 @@ const StaticExtFilteringHostnameDB = class {
67
76
68
77
clear() {
69
78
this.hostnameToSlotIdMap.clear();
79
+
this.regexToSlotIdMap.clear();
70
80
this.hostnameSlots.length = 0;
71
81
this.strSlots.length = 0;
72
82
this.strToIdMap.clear();
83
+
this.regexMap.clear();
73
84
this.size = 0;
74
85
}
75
86
@@ -92,39 +103,55 @@ const StaticExtFilteringHostnameDB = class {
92
103
);
93
104
}
94
105
95
-
// modifiers = 1: return only specific items
96
-
// modifiers = 2: return only generic items
106
+
// modifiers = 0: all items
107
+
// modifiers = 1: only specific items
108
+
// modifiers = 2: only generic items
109
+
// modifiers = 3: only regex-based items
97
110
//
98
111
retrieve(hostname, out, modifiers = 0) {
99
-
if ( modifiers === 2 ) {
100
-
hostname = '';
101
-
}
112
+
let hn = hostname;
113
+
if ( modifiers === 2 ) { hn = ''; }
102
114
const mask = out.length - 1; // out.length must be power of two
103
115
for (;;) {
104
-
let iHn = this.hostnameToSlotIdMap.get(hostname);
116
+
let iHn = this.hostnameToSlotIdMap.get(hn);
105
117
if ( iHn !== undefined ) {
106
118
do {
107
119
const strId = this.hostnameSlots[iHn+0];
108
-
out[strId & mask].add(
109
-
this.strSlots[strId >>> this.nBits]
110
-
);
120
+
out[strId & mask].add(this.strSlots[strId >>> this.nBits]);
111
121
iHn = this.hostnameSlots[iHn+1];
112
122
} while ( iHn !== 0 );
113
123
}
114
-
if ( hostname === '' ) { break; }
115
-
const pos = hostname.indexOf('.');
124
+
if ( hn === '' ) { break; }
125
+
const pos = hn.indexOf('.');
116
126
if ( pos === -1 ) {
117
127
if ( modifiers === 1 ) { break; }
118
-
hostname = '';
128
+
hn = '';
119
129
} else {
120
-
hostname = hostname.slice(pos + 1);
130
+
hn = hn.slice(pos + 1);
121
131
}
122
132
}
133
+
if ( modifiers !== 0 && modifiers !== 3 ) { return; }
134
+
// TODO: consider using a combined regex to test once for whether
135
+
// iterating is worth it.
136
+
for ( const restr of this.regexToSlotIdMap.keys() ) {
137
+
let re = this.regexMap.get(restr);
138
+
if ( re === undefined ) {
139
+
this.regexMap.set(restr, (re = new RegExp(restr.slice(1,-1))));
140
+
}
141
+
if ( re.test(hostname) === false ) { continue; }
142
+
let iHn = this.regexToSlotIdMap.get(restr);
143
+
do {
144
+
const strId = this.hostnameSlots[iHn+0];
145
+
out[strId & mask].add(this.strSlots[strId >>> this.nBits]);
146
+
iHn = this.hostnameSlots[iHn+1];
147
+
} while ( iHn !== 0 );
148
+
}
123
149
}
124
150
125
151
toSelfie() {
126
152
return {
127
153
hostnameToSlotIdMap: Array.from(this.hostnameToSlotIdMap),
154
+
regexToSlotIdMap: Array.from(this.regexToSlotIdMap),
128
155
hostnameSlots: this.hostnameSlots,
129
156
strSlots: this.strSlots,
130
157
size: this.size
@@ -134,6 +161,10 @@ const StaticExtFilteringHostnameDB = class {
134
161
fromSelfie(selfie) {
135
162
if ( selfie === undefined ) { return; }
136
163
this.hostnameToSlotIdMap = new Map(selfie.hostnameToSlotIdMap);
164
+
// Regex-based lookup available in uBO 1.47.0 and above
165
+
if ( Array.isArray(selfie.regexToSlotIdMap) ) {
166
+
this.regexToSlotIdMap = new Map(selfie.regexToSlotIdMap);
167
+
}
137
168
this.hostnameSlots = selfie.hostnameSlots;
138
169
this.strSlots = selfie.strSlots;
139
170
this.size = selfie.size;
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4