2021-01-01 14:27:58 +00:00
|
|
|
/* global API */// msg.js
|
2021-01-26 13:33:17 +00:00
|
|
|
/* global RX_META debounce stringAsRegExp tryRegExp */// toolbox.js
|
2021-01-01 14:27:58 +00:00
|
|
|
/* global addAPI */// common.js
|
2018-01-01 17:02:49 +00:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
(() => {
|
|
|
|
// toLocaleLowerCase cache, autocleared after 1 minute
|
|
|
|
const cache = new Map();
|
2020-11-18 11:17:15 +00:00
|
|
|
const METAKEYS = ['customName', 'name', 'url', 'installationUrl', 'updateUrl'];
|
|
|
|
|
|
|
|
const extractMeta = style =>
|
|
|
|
style.usercssData
|
2021-01-26 13:33:17 +00:00
|
|
|
? (style.sourceCode.match(RX_META) || [''])[0]
|
2020-11-18 11:17:15 +00:00
|
|
|
: null;
|
|
|
|
|
|
|
|
const stripMeta = style =>
|
|
|
|
style.usercssData
|
2021-01-26 13:33:17 +00:00
|
|
|
? style.sourceCode.replace(RX_META, '')
|
2020-11-18 11:17:15 +00:00
|
|
|
: null;
|
|
|
|
|
|
|
|
const MODES = Object.assign(Object.create(null), {
|
|
|
|
code: (style, test) =>
|
|
|
|
style.usercssData
|
|
|
|
? test(stripMeta(style))
|
|
|
|
: searchSections(style, test, 'code'),
|
|
|
|
|
|
|
|
meta: (style, test, part) =>
|
|
|
|
METAKEYS.some(key => test(style[key])) ||
|
2021-01-01 14:27:58 +00:00
|
|
|
test(part === 'all' ? style.sourceCode : extractMeta(style)) ||
|
|
|
|
searchSections(style, test, 'funcs'),
|
2020-11-18 11:17:15 +00:00
|
|
|
|
|
|
|
name: (style, test) =>
|
|
|
|
test(style.customName) ||
|
|
|
|
test(style.name),
|
|
|
|
|
|
|
|
all: (style, test) =>
|
|
|
|
MODES.meta(style, test, 'all') ||
|
|
|
|
!style.usercssData && MODES.code(style, test),
|
|
|
|
});
|
2018-01-01 17:02:49 +00:00
|
|
|
|
2021-01-01 14:27:58 +00:00
|
|
|
addAPI(/** @namespace API */ {
|
|
|
|
styles: {
|
|
|
|
/**
|
|
|
|
* @param params
|
|
|
|
* @param {string} params.query - 1. url:someurl 2. text (may contain quoted parts like "qUot Ed")
|
|
|
|
* @param {'name'|'meta'|'code'|'all'|'url'} [params.mode=all]
|
|
|
|
* @param {number[]} [params.ids] - if not specified, all styles are searched
|
|
|
|
* @returns {number[]} - array of matched styles ids
|
|
|
|
*/
|
|
|
|
async searchDB({query, mode = 'all', ids}) {
|
|
|
|
let res = [];
|
|
|
|
if (mode === 'url' && query) {
|
|
|
|
res = (await API.styles.getByUrl(query)).map(r => r.style.id);
|
|
|
|
} else if (mode in MODES) {
|
|
|
|
const modeHandler = MODES[mode];
|
|
|
|
const m = /^\/(.+?)\/([gimsuy]*)$/.exec(query);
|
|
|
|
const rx = m && tryRegExp(m[1], m[2]);
|
|
|
|
const test = rx ? rx.test.bind(rx) : createTester(query);
|
|
|
|
res = (await API.styles.getAll())
|
|
|
|
.filter(style =>
|
|
|
|
(!ids || ids.includes(style.id)) &&
|
|
|
|
(!query || modeHandler(style, test)))
|
|
|
|
.map(style => style.id);
|
|
|
|
if (cache.size) debounce(clearCache, 60e3);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
});
|
2018-01-01 17:02:49 +00:00
|
|
|
|
2021-01-01 14:27:58 +00:00
|
|
|
function createTester(query) {
|
2020-11-18 11:17:15 +00:00
|
|
|
const flags = `u${lower(query) === query ? 'i' : ''}`;
|
|
|
|
const words = query
|
|
|
|
.split(/(".*?")|\s+/)
|
|
|
|
.filter(Boolean)
|
|
|
|
.map(w => w.startsWith('"') && w.endsWith('"')
|
|
|
|
? w.slice(1, -1)
|
|
|
|
: w)
|
|
|
|
.filter(w => w.length > 1);
|
|
|
|
const rxs = (words.length ? words : [query])
|
|
|
|
.map(w => stringAsRegExp(w, flags));
|
|
|
|
return text => rxs.every(rx => rx.test(text));
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
|
|
|
|
2020-11-18 11:17:15 +00:00
|
|
|
function searchSections({sections}, test, part) {
|
|
|
|
const inCode = part === 'code' || part === 'all';
|
|
|
|
const inFuncs = part === 'funcs' || part === 'all';
|
2018-01-01 17:02:49 +00:00
|
|
|
for (const section of sections) {
|
|
|
|
for (const prop in section) {
|
|
|
|
const value = section[prop];
|
2020-11-18 11:17:15 +00:00
|
|
|
if (inCode && prop === 'code' && test(value) ||
|
|
|
|
inFuncs && Array.isArray(value) && value.some(str => test(str))) {
|
|
|
|
return true;
|
2018-01-01 17:02:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function lower(text) {
|
|
|
|
let result = cache.get(text);
|
2020-11-18 11:17:15 +00:00
|
|
|
if (!result) cache.set(text, result = text.toLocaleLowerCase());
|
2018-01-01 17:02:49 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearCache() {
|
|
|
|
cache.clear();
|
|
|
|
}
|
|
|
|
})();
|