Optimize filters:
- Use Map for string - in valueF functions return empty array instead of \[undefined\] to skip iterating over filters for empty values
This commit is contained in:
parent
f80be7613a
commit
4bd91ce2d8
@ -12,6 +12,7 @@ import { dict } from "../platform/helpers";
|
|||||||
import QuoteYou from "../Quotelinks/QuoteYou";
|
import QuoteYou from "../Quotelinks/QuoteYou";
|
||||||
import PostHiding from "./PostHiding";
|
import PostHiding from "./PostHiding";
|
||||||
import ThreadHiding from "./ThreadHiding";
|
import ThreadHiding from "./ThreadHiding";
|
||||||
|
import type Post from "../classes/Post";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* decaffeinate suggestions:
|
* decaffeinate suggestions:
|
||||||
@ -21,9 +22,31 @@ import ThreadHiding from "./ThreadHiding";
|
|||||||
* DS207: Consider shorter variations of null checks
|
* DS207: Consider shorter variations of null checks
|
||||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/main/docs/suggestions.md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
interface FilterObj {
|
||||||
|
isstring: boolean;
|
||||||
|
regexp: string | RegExp;
|
||||||
|
boards: any;
|
||||||
|
excludes: any;
|
||||||
|
mask: any;
|
||||||
|
hide: boolean;
|
||||||
|
stub: any;
|
||||||
|
hl: string;
|
||||||
|
top: boolean;
|
||||||
|
noti: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterType = "postID" | "name" | "uniqueID" | "tripcode" | "capcode" | "pass" | "email" | "subject" | "comment"
|
||||||
|
| "flag" | "filename" | "dimensions" | "filesize" | "MD5";
|
||||||
|
|
||||||
var Filter = {
|
var Filter = {
|
||||||
filters: dict(),
|
/**
|
||||||
init() {
|
* Uses a Map for string types, with the value to filter for as the key.
|
||||||
|
* This allows faster lookup than iterating over every filter.
|
||||||
|
*/
|
||||||
|
filters: new Map<FilterType, FilterObj[] | Map<string, FilterObj[]>>(),
|
||||||
|
|
||||||
|
init(this: typeof Filter) {
|
||||||
if (!['index', 'thread', 'catalog'].includes(g.VIEW) || !Conf['Filter']) { return; }
|
if (!['index', 'thread', 'catalog'].includes(g.VIEW) || !Conf['Filter']) { return; }
|
||||||
if ((g.VIEW === 'catalog') && !Conf['Filter in Native Catalog']) { return; }
|
if ((g.VIEW === 'catalog') && !Conf['Filter in Native Catalog']) { return; }
|
||||||
|
|
||||||
@ -32,8 +55,13 @@ var Filter = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (var key in Config.filter) {
|
for (var key in Config.filter) {
|
||||||
for (var line of Conf[key].split('\n')) {
|
for (var line of (Conf[key] as string).split('\n')) {
|
||||||
var hl, isstring, regexp, top, types;
|
let hl: string;
|
||||||
|
let isstring: boolean;
|
||||||
|
let regexp: RegExp | string;
|
||||||
|
let top: boolean;
|
||||||
|
let types: string[];
|
||||||
|
|
||||||
if (line[0] === '#') { continue; }
|
if (line[0] === '#') { continue; }
|
||||||
|
|
||||||
if (!(regexp = line.match(/\/(.*)\/(\w*)/))) {
|
if (!(regexp = line.match(/\/(.*)\/(\w*)/))) {
|
||||||
@ -113,18 +141,32 @@ var Filter = {
|
|||||||
// Hide the post (default case).
|
// Hide the post (default case).
|
||||||
var hide = !(hl || noti);
|
var hide = !(hl || noti);
|
||||||
|
|
||||||
filter = {isstring, regexp, boards, excludes, mask, hide, stub, hl, top, noti};
|
const filterObj = { isstring, regexp, boards, excludes, mask, hide, stub, hl, top, noti };
|
||||||
if (key === 'general') {
|
if (key === 'general') {
|
||||||
for (var type of types) {
|
for (var type of types) {
|
||||||
(this.filters[type] || (this.filters[type] = [])).push(filter);
|
this.filters.get(type)?.push(filterObj) ?? this.filters.set(type, [filterObj]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(this.filters[key] || (this.filters[key] = [])).push(filter);
|
this.filters.get(key)?.push(filterObj) ?? this.filters.set(key, [filterObj]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Object.keys(this.filters).length) { return; }
|
if (!this.filters.size) return;
|
||||||
|
|
||||||
|
// conversion from array to map for string types
|
||||||
|
for (const type of ['MD5', 'uniqueID'] satisfies FilterType[]) {
|
||||||
|
const filtersForType = this.filters.get(type);
|
||||||
|
if (!filtersForType) continue;
|
||||||
|
|
||||||
|
const map = new Map<string, FilterObj[]>();
|
||||||
|
for (const filter of filtersForType) {
|
||||||
|
map.get(filter.regexp)?.push(filter) ?? map.set(filter.regexp, [filter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.filters.set(type, map);
|
||||||
|
}
|
||||||
|
|
||||||
if (g.VIEW === 'catalog') {
|
if (g.VIEW === 'catalog') {
|
||||||
return Filter.catalog();
|
return Filter.catalog();
|
||||||
} else {
|
} else {
|
||||||
@ -166,7 +208,7 @@ var Filter = {
|
|||||||
|
|
||||||
parseBoardsMemo: dict(),
|
parseBoardsMemo: dict(),
|
||||||
|
|
||||||
test(post, hideable=true) {
|
test(post: Post, hideable = true) {
|
||||||
if (post.filterResults) { return post.filterResults; }
|
if (post.filterResults) { return post.filterResults; }
|
||||||
let hide = false;
|
let hide = false;
|
||||||
let stub = true;
|
let stub = true;
|
||||||
@ -180,9 +222,14 @@ var Filter = {
|
|||||||
mask = (mask | (post.file ? 4 : 8));
|
mask = (mask | (post.file ? 4 : 8));
|
||||||
const board = `${post.siteID}/${post.boardID}`;
|
const board = `${post.siteID}/${post.boardID}`;
|
||||||
const site = `${post.siteID}/*`;
|
const site = `${post.siteID}/*`;
|
||||||
for (var key in Filter.filters) {
|
for (const key of Filter.filters.keys()) {
|
||||||
for (var value of Filter.values(key, post)) {
|
for (const value of Filter.values(key, post)) {
|
||||||
for (var filter of Filter.filters[key]) {
|
const filtersOrMap = Filter.filters.get(key);
|
||||||
|
|
||||||
|
const filtersForType = Array.isArray(filtersOrMap) ? filtersOrMap : filtersOrMap.get(value);
|
||||||
|
if (!filtersForType) continue;
|
||||||
|
|
||||||
|
for (const filter of filtersForType) {
|
||||||
if (
|
if (
|
||||||
(filter.boards && !(filter.boards[board] || filter.boards[site] )) ||
|
(filter.boards && !(filter.boards[board] || filter.boards[site] )) ||
|
||||||
(filter.excludes && (filter.excludes[board] || filter.excludes[site])) ||
|
(filter.excludes && (filter.excludes[board] || filter.excludes[site])) ||
|
||||||
@ -217,7 +264,7 @@ var Filter = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
node() {
|
node(this: Post) {
|
||||||
if (this.isClone) { return; }
|
if (this.isClone) { return; }
|
||||||
const {hide, stub, hl, top, noti} = Filter.test(this, (!this.isFetchedQuote && (this.isReply || (g.VIEW === 'index'))));
|
const {hide, stub, hl, top, noti} = Filter.test(this, (!this.isFetchedQuote && (this.isReply || (g.VIEW === 'index'))));
|
||||||
if (hide) {
|
if (hide) {
|
||||||
@ -284,33 +331,38 @@ var Filter = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isHidden(post) {
|
isHidden(post: Post) {
|
||||||
return !!Filter.test(post).hide;
|
return !!Filter.test(post).hide;
|
||||||
},
|
},
|
||||||
|
|
||||||
valueF: {
|
valueF: {
|
||||||
postID(post) { return [`${post.ID}`]; },
|
postID (post) { return [`${post.ID}`]; },
|
||||||
name(post) { return [post.info.name]; },
|
name(post) { return post.info.name === undefined ? [] : [post.info.name]; },
|
||||||
uniqueID(post) { return [post.info.uniqueID || '']; },
|
uniqueID(post) { return [post.info.uniqueID || '']; },
|
||||||
tripcode(post) { return [post.info.tripcode]; },
|
tripcode(post) { return post.info.tripcode === undefined ? [] : [post.info.tripcode]; },
|
||||||
capcode(post) { return [post.info.capcode]; },
|
capcode(post) { return post.info.capcode === undefined ? [] : [post.info.capcode]; },
|
||||||
pass(post) { return [post.info.pass]; },
|
pass(post) { return [post.info.pass]; },
|
||||||
email(post) { return [post.info.email]; },
|
email(post) { return [post.info.email]; },
|
||||||
subject(post) { return [post.info.subject || (post.isReply ? undefined : '')]; },
|
subject(post) { return [post.info.subject || (post.isReply ? undefined : '')]; },
|
||||||
comment(post) { return [(post.info.comment != null ? post.info.comment : (post.info.comment = g.sites[post.siteID]?.Build?.parseComment?.(post.info.commentHTML.innerHTML)))]; },
|
comment(post) {
|
||||||
flag(post) { return [post.info.flag]; },
|
if (post.info.comment == null) {
|
||||||
|
post.info.comment = g.sites[post.siteID]?.Build?.parseComment?.(post.info.commentHTML.innerHTML);
|
||||||
|
}
|
||||||
|
return [post.info.comment];
|
||||||
|
},
|
||||||
|
flag(post) { return post.info.flag === undefined ? [] : [post.info.flag]; },
|
||||||
filename(post) { return post.files.map(f => f.name); },
|
filename(post) { return post.files.map(f => f.name); },
|
||||||
dimensions(post) { return post.files.map(f => f.dimensions); },
|
dimensions(post) { return post.files.map(f => f.dimensions); },
|
||||||
filesize(post) { return post.files.map(f => f.size); },
|
filesize(post) { return post.files.map(f => f.size); },
|
||||||
MD5(post) { return post.files.map(f => f.MD5); }
|
MD5(post) { return post.files.map(f => f.MD5); }
|
||||||
},
|
} satisfies Record<FilterType, (post: Post) => string[]>,
|
||||||
|
|
||||||
values(key, post) {
|
values(key: FilterType, post: Post): string[] {
|
||||||
if ($.hasOwn(Filter.valueF, key)) {
|
if ($.hasOwn(Filter.valueF, key)) {
|
||||||
return Filter.valueF[key](post).filter(v => v != null);
|
return Filter.valueF[key](post).filter(v => v != null);
|
||||||
} else {
|
} else {
|
||||||
return [key.split('+').map(function(k) {
|
return [key.split('+').map(function(k) {
|
||||||
let f;
|
let f: (post: Post) => string[];
|
||||||
if (f = $.getOwn(Filter.valueF, k)) {
|
if (f = $.getOwn(Filter.valueF, k)) {
|
||||||
return f(post).map(v => v || '').join('\n');
|
return f(post).map(v => v || '').join('\n');
|
||||||
} else {
|
} else {
|
||||||
@ -320,7 +372,7 @@ var Filter = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
addFilter(type, re, cb) {
|
addFilter(type: FilterType, re: string, cb?: () => void) {
|
||||||
if (!$.hasOwn(Config.filter, type)) { return; }
|
if (!$.hasOwn(Config.filter, type)) { return; }
|
||||||
return $.get(type, Conf[type], function(item) {
|
return $.get(type, Conf[type], function(item) {
|
||||||
let save = item[type];
|
let save = item[type];
|
||||||
@ -334,11 +386,12 @@ var Filter = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
removeFilters(type, res, cb) {
|
removeFilters(type: FilterType, res: FilterObj[] | Map<string, FilterObj[]>, cb?: () => void) {
|
||||||
return $.get(type, Conf[type], function(item) {
|
return $.get(type, Conf[type], function (item) {
|
||||||
let save = item[type];
|
let save = item[type];
|
||||||
res = res.map(Filter.escape).join('|');
|
const filterArray = Array.isArray(res) ? res : [...res.values()].flat();
|
||||||
save = save.replace(RegExp(`(?:$\n|^)(?:${res})$`, 'mg'), '');
|
const r = filterArray.map(Filter.escape).join('|');
|
||||||
|
save = save.replace(RegExp(`(?:$\n|^)(?:${r})$`, 'mg'), '');
|
||||||
return $.set(type, save, cb);
|
return $.set(type, save, cb);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -358,7 +411,7 @@ var Filter = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
quickFilterMD5() {
|
quickFilterMD5() {
|
||||||
const post = Get.postFromNode(this);
|
const post: Post = Get.postFromNode(this);
|
||||||
const files = post.files.filter(f => f.MD5);
|
const files = post.files.filter(f => f.MD5);
|
||||||
if (!files.length) { return; }
|
if (!files.length) { return; }
|
||||||
const filter = files.map(f => `/${f.MD5}/`).join('\n');
|
const filter = files.map(f => `/${f.MD5}/`).join('\n');
|
||||||
@ -473,7 +526,7 @@ var Filter = {
|
|||||||
['Image dimensions', 'dimensions'],
|
['Image dimensions', 'dimensions'],
|
||||||
['Filesize', 'filesize'],
|
['Filesize', 'filesize'],
|
||||||
['Image MD5', 'MD5']
|
['Image MD5', 'MD5']
|
||||||
]) {
|
] satisfies [string, FilterType][]) {
|
||||||
// Add a sub entry for each filter type.
|
// Add a sub entry for each filter type.
|
||||||
entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1]));
|
entry.subEntries.push(Filter.menu.createSubEntry(type[0], type[1]));
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user