59 lines
1.3 KiB
JavaScript
59 lines
1.3 KiB
JavaScript
export class Filter {
|
|
match = [];
|
|
negate = [];
|
|
|
|
constructor(query) {
|
|
query ??= "";
|
|
query = query.trim();
|
|
|
|
// https://stackoverflow.com/a/16261693
|
|
for (let match of (query.match(/(?:[^\s"]+|"[^"]*")+/g) ?? [])) {
|
|
const negate = match[0] === '-';
|
|
if (negate) {
|
|
match = match.slice(1);
|
|
}
|
|
|
|
if (match[0] === '"' && match[match.length - 1] === '"') {
|
|
match = match.slice(1, match.length - 1);
|
|
}
|
|
|
|
match = match.trim().toLocaleLowerCase();
|
|
|
|
if (!match) continue;
|
|
|
|
if (negate) {
|
|
this.negate.push(match);
|
|
} else {
|
|
this.match.push(match);
|
|
}
|
|
}
|
|
}
|
|
|
|
static fromInput(dataValue) {
|
|
const elem = document.querySelector(`[data-input='${dataValue}']`);
|
|
return new Filter(elem.value);
|
|
}
|
|
|
|
test(...data) {
|
|
for (const datum of data) {
|
|
if (typeof datum !== "string") {
|
|
console.log("cannot test %o", datum);
|
|
continue;
|
|
}
|
|
|
|
const normalized = datum.trim().toLocaleLowerCase().trim();
|
|
for (const n of this.negate) {
|
|
if (normalized.includes(n)) {
|
|
return false;
|
|
}
|
|
}
|
|
for (const m of this.match) {
|
|
if (normalized.includes(m)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return this.match.length === 0;
|
|
}
|
|
}
|