/** * Myext querying page settings with regard to wildcard records * * Copyright (C) 2021 Wojtek Kosior * Redistribution terms are gathered in the `copyright' file. */ /* * IMPORTS_START * IMPORT make_once * IMPORT get_storage * IMPORT TYPE_PREFIX * IMPORTS_END */ var storage; var exports = {}; async function init(fun) { storage = await get_storage(); return fun; } // TODO: also support urls with specified ports 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); } const get_query_best = make_once(() => init(query_best)); const get_query_all = make_once(() => init(query_all)); /* * EXPORTS_START * EXPORT get_query_best * EXPORT get_query_all * EXPORTS_END */