Skip to content

Commit 519b4a0

Browse files
authored
feat: enhanced domain filtering (#100)
1 parent 4a2e19f commit 519b4a0

3 files changed

Lines changed: 46 additions & 4 deletions

File tree

background/index.ts

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,13 @@ function downloadFilter(info: DownloadInfo, settings: Settings): boolean {
196196
}
197197
if (settings.excludeDomains.enabled) {
198198
const excludes = settings.excludeDomains.list.split("\n")
199+
.map(ex => ex.trim())
200+
.filter(ex => ex.length > 0)
199201
const host = new URL(info.url).host
200-
if (excludes.includes(host)) {
201-
return false
202+
for (const exclude of excludes) {
203+
if (isDomainMatch(host, exclude)) {
204+
return false
205+
}
202206
}
203207
}
204208
if (settings.excludeFileTypes.enabled && info.filename) {
@@ -624,3 +628,41 @@ async function toCreateRequest(info: DownloadInfo): Promise<Request> {
624628
}
625629
}
626630
}
631+
632+
function isDomainMatch(host: string, pattern: string): boolean {
633+
const patternLen = pattern.length;
634+
635+
// Handle different pattern types based on leading/trailing characters
636+
if (patternLen > 2 && pattern[0] === '*' && pattern[patternLen - 1] === '*') {
637+
// Contains match: *example.com* matches any domain containing example.com
638+
const middlePattern = pattern.substring(1, patternLen - 1);
639+
return host.includes(middlePattern);
640+
}
641+
642+
if (patternLen > 1 && pattern[0] === '*') {
643+
if (pattern[1] === '.') {
644+
// Subdomain match: *.example.com matches subdomains but not the domain itself
645+
const parentDomain = pattern.substring(2); // example.com
646+
return host !== parentDomain && host.endsWith('.' + parentDomain);
647+
} else {
648+
// All match: *example.com matches domain and all subdomains
649+
const parentDomain = pattern.substring(1); // example.com
650+
return host === parentDomain || host.endsWith('.' + parentDomain);
651+
}
652+
}
653+
654+
if (patternLen > 1 && pattern[0] === '/' && pattern[patternLen - 1] === '/') {
655+
// Regex match: /pattern/ matches using regular expression
656+
try {
657+
const regexPattern = pattern.substring(1, patternLen - 1);
658+
const regex = new RegExp(regexPattern);
659+
return regex.test(host);
660+
} catch (e) {
661+
console.warn(`Invalid regex pattern: ${pattern}`);
662+
return false;
663+
}
664+
}
665+
666+
// Exact match: example.com only matches example.com
667+
return pattern === host;
668+
}

locales/en/messages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"message": "Set domains that do not need to be captured"
4343
},
4444
"domain_filter_placeholder": {
45-
"message": "Enter one domain per line, e.g.: example.com"
45+
"message": "Enter one domain per line. Supports exact match (example.com), subdomain match (*.example.com), all match (*example.com), and contains match (*example.com*)"
4646
},
4747
"file_type_filter": {
4848
"message": "File Type Filter"

locales/zh/messages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"message": "设置不需要捕获的域名"
4343
},
4444
"domain_filter_placeholder": {
45-
"message": "每行输入一个域名,例如:example.com"
45+
"message": "每行输入一个域名,支持精确匹配 (example.com)、子域名匹配 (*.example.com)、全匹配 (*example.com) 和包含匹配 (*example.com*)"
4646
},
4747
"file_type_filter": {
4848
"message": "文件类型过滤"

0 commit comments

Comments
 (0)