From 68d557db3eb0c050ff0027429922202ef97c1fe1 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Fri, 14 May 2021 18:18:51 +0200 Subject: support wildcard urls in settings --- background/settings_query.js | 130 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 background/settings_query.js (limited to 'background/settings_query.js') diff --git a/background/settings_query.js b/background/settings_query.js new file mode 100644 index 0000000..9101913 --- /dev/null +++ b/background/settings_query.js @@ -0,0 +1,130 @@ +/** +* Myext querying page settings with regard to wildcard records +* +* Copyright (C) 2021 Wojtek Kosior +* +* Dual-licensed under: +* - 0BSD license +* - GPLv3 or (at your option) any later version +*/ + +"use strict"; + +(() => { + const make_once = window.make_once; + const get_storage = window.get_storage; + + var storage; + + var exports = {}; + + async function init(fun) + { + storage = await get_storage(); + + return fun; + } + + // TODO: also support urls with specified ports as well as `data:' urls + function query(url, multiple) + { + let proto_re = "[a-zA-Z]*:\/\/"; + let domain_re = "[^/?#]+"; + let segments_re = "/[^?#]*"; + let query_re = "\\?[^#]*"; + + let url_regex = new RegExp(`\ +^\ +(${proto_re})\ +(${domain_re})\ +(${segments_re})?\ +(${query_re})?\ +#?.*\$\ +`); + + let regex_match = url_regex.exec(url); + if (regex_match === null) { + console.log("bad url format", url); + return multiple ? [] : [undefined, undefined]; + } + + let [_, proto, domain, segments, query] = regex_match; + + domain = domain.split("."); + let segments_trailing_dash = + segments && segments[segments.length - 1] === "/"; + segments = (segments || "").split("/").filter(s => s !== ""); + segments.unshift(""); + + let matched = []; + + for (let d_slice = 0; d_slice < domain.length; d_slice++) { + let domain_part = domain.slice(d_slice).join("."); + let domain_wildcards = []; + if (d_slice === 0) + domain_wildcards.push(""); + if (d_slice === 1) + domain_wildcards.push("*."); + if (d_slice > 0) + domain_wildcards.push("**."); + domain_wildcards.push("***."); + + for (let domain_wildcard of domain_wildcards) { + let domain_pattern = domain_wildcard + domain_part; + + for (let s_slice = segments.length; s_slice > 0; s_slice--) { + let segments_part = segments.slice(0, s_slice).join("/"); + let segments_wildcards = []; + if (s_slice === segments.length) { + if (segments_trailing_dash) + segments_wildcards.push("/"); + segments_wildcards.push(""); + } + if (s_slice === segments.length - 1) { + if (segments[s_slice] !== "*") + segments_wildcards.push("/*"); + } + if (s_slice < segments.length && + (segments[s_slice] !== "**" || + s_slice < segments.length - 1)) + segments_wildcards.push("/**"); + if (segments[s_slice] !== "***" || + s_slice < segments.length) + segments_wildcards.push("/***"); + + for (let segments_wildcard of segments_wildcards) { + let segments_pattern = + segments_part + segments_wildcard; + + let pattern = proto + domain_pattern + segments_pattern; + console.log("trying", pattern); + let settings = storage.get(TYPE_PREFIX.PAGE, pattern); + + if (settings === undefined) + continue; + + if (!multiple) + return [pattern, settings]; + + matched.push([pattern, settings]); + } + } + } + } + + return multiple ? matched : [undefined, undefined]; + } + + function query_best(url) + { + return query(url, false); + } + + function query_all(url) + { + return query(url, true); + } + + window.get_query_best = make_once(() => init(query_best)); + window.get_query_all = make_once(() => init(query_all)); +})(); -- cgit v1.2.3