Project

General

Profile

Download (3.89 KB) Statistics
| Branch: | Tag: | Revision:

haketilo / background / settings_query.js @ 6bae771d

1
/**
2
 * Myext querying page settings with regard to wildcard records
3
 *
4
 * Copyright (C) 2021 Wojtek Kosior
5
 *
6
 * This code is dual-licensed under:
7
 * - Asshole license 1.0,
8
 * - GPLv3 or (at your option) any later version
9
 *
10
 * "dual-licensed" means you can choose the license you prefer.
11
 *
12
 * This code is released under a permissive license because I disapprove of
13
 * copyright and wouldn't be willing to sue a violator. Despite not putting
14
 * this code under copyleft (which is also kind of copyright), I do not want
15
 * it to be made proprietary. Hence, the permissive alternative to GPL is the
16
 * Asshole license 1.0 that allows me to call you an asshole if you use it.
17
 * This means you're legally ok regardless of how you utilize this code but if
18
 * you make it into something nonfree, you're an asshole.
19
 *
20
 * You should have received a copy of both GPLv3 and Asshole license 1.0
21
 * together with this code. If not, please see:
22
 * - https://www.gnu.org/licenses/gpl-3.0.en.html
23
 * - https://koszko.org/asshole-license.txt
24
 */
25

    
26
"use strict";
27

    
28
(() => {
29
    const make_once = window.make_once;
30
    const get_storage = window.get_storage;
31

    
32
    var storage;
33

    
34
    var exports = {};
35

    
36
    async function init(fun)
37
    {
38
	storage = await get_storage();
39

    
40
	return fun;
41
    }
42

    
43
    // TODO: also support urls with specified ports as well as `data:' urls
44
    function query(url, multiple)
45
    {
46
	let proto_re = "[a-zA-Z]*:\/\/";
47
	let domain_re = "[^/?#]+";
48
	let segments_re = "/[^?#]*";
49
	let query_re = "\\?[^#]*";
50

    
51
	let url_regex = new RegExp(`\
52
^\
53
(${proto_re})\
54
(${domain_re})\
55
(${segments_re})?\
56
(${query_re})?\
57
#?.*\$\
58
`);
59

    
60
	let regex_match = url_regex.exec(url);
61
	if (regex_match === null) {
62
	    console.log("bad url format", url);
63
	    return multiple ? [] : [undefined, undefined];
64
	}
65

    
66
	let [_, proto, domain, segments, query] = regex_match;
67

    
68
	domain = domain.split(".");
69
	let segments_trailing_dash =
70
	    segments && segments[segments.length - 1] === "/";
71
	segments = (segments || "").split("/").filter(s => s !== "");
72
	segments.unshift("");
73

    
74
	let matched = [];
75

    
76
	for (let d_slice = 0; d_slice < domain.length; d_slice++) {
77
	    let domain_part = domain.slice(d_slice).join(".");
78
	    let domain_wildcards = [];
79
	    if (d_slice === 0)
80
		domain_wildcards.push("");
81
	    if (d_slice === 1)
82
		domain_wildcards.push("*.");
83
	    if (d_slice > 0)
84
		domain_wildcards.push("**.");
85
	    domain_wildcards.push("***.");
86

    
87
	    for (let domain_wildcard of domain_wildcards) {
88
		let domain_pattern = domain_wildcard + domain_part;
89

    
90
		for (let s_slice = segments.length; s_slice > 0; s_slice--) {
91
		    let segments_part = segments.slice(0, s_slice).join("/");
92
		    let segments_wildcards = [];
93
		    if (s_slice === segments.length) {
94
			if (segments_trailing_dash)
95
			    segments_wildcards.push("/");
96
			segments_wildcards.push("");
97
		    }
98
		    if (s_slice === segments.length - 1) {
99
			if (segments[s_slice] !== "*")
100
			    segments_wildcards.push("/*");
101
		    }
102
		    if (s_slice < segments.length &&
103
			(segments[s_slice] !== "**" ||
104
			 s_slice < segments.length - 1))
105
			segments_wildcards.push("/**");
106
		    if (segments[s_slice] !== "***" ||
107
			s_slice < segments.length)
108
			segments_wildcards.push("/***");
109

    
110
		    for (let segments_wildcard of segments_wildcards) {
111
			let segments_pattern =
112
			    segments_part + segments_wildcard;
113

    
114
			let pattern = proto + domain_pattern + segments_pattern;
115
			console.log("trying", pattern);
116
			let settings = storage.get(TYPE_PREFIX.PAGE, pattern);
117

    
118
			if (settings === undefined)
119
			    continue;
120

    
121
			if (!multiple)
122
			    return [pattern, settings];
123

    
124
			matched.push([pattern, settings]);
125
		    }
126
		}
127
	    }
128
	}
129

    
130
	return multiple ?  matched : [undefined, undefined];
131
    }
132

    
133
    function query_best(url)
134
    {
135
	return query(url, false);
136
    }
137

    
138
    function query_all(url)
139
    {
140
	return query(url, true);
141
    }
142

    
143
    window.get_query_best = make_once(() => init(query_best));
144
    window.get_query_all = make_once(() => init(query_all));
145
})();
(7-7/9)