Revision 6247f163
Added by koszko about 2 years ago
background/main.js | ||
---|---|---|
9 | 9 |
* IMPORTS_START |
10 | 10 |
* IMPORT TYPE_PREFIX |
11 | 11 |
* IMPORT get_storage |
12 |
* IMPORT light_storage |
|
12 | 13 |
* IMPORT start_storage_server |
13 | 14 |
* IMPORT start_page_actions_server |
14 | 15 |
* IMPORT browser |
... | ... | |
50 | 51 |
|
51 | 52 |
|
52 | 53 |
let storage; |
54 |
let policy_observable = {}; |
|
53 | 55 |
|
54 | 56 |
function on_headers_received(details) |
55 | 57 |
{ |
... | ... | |
58 | 60 |
return; |
59 | 61 |
|
60 | 62 |
const [pattern, settings] = query_best(storage, details.url); |
61 |
const allow = !!(settings && settings.allow);
|
|
63 |
const allow = !!(settings ? settings.allow : policy_observable.value);
|
|
62 | 64 |
const nonce = gen_nonce(); |
63 | 65 |
const policy = {allow, url, nonce}; |
64 | 66 |
|
... | ... | |
114 | 116 |
{urls: ["<all_urls>"], types: all_types}, |
115 | 117 |
extra_opts.concat("requestHeaders") |
116 | 118 |
); |
119 |
|
|
120 |
policy_observable = await light_storage.observe_var("default_allow"); |
|
117 | 121 |
} |
118 | 122 |
|
119 | 123 |
start_webRequest_operations(); |
background/page_actions_server.js | ||
---|---|---|
8 | 8 |
/* |
9 | 9 |
* IMPORTS_START |
10 | 10 |
* IMPORT get_storage |
11 |
* IMPORT light_storage |
|
11 | 12 |
* IMPORT TYPE_PREFIX |
12 | 13 |
* IMPORT CONNECTION_TYPE |
13 | 14 |
* IMPORT browser |
... | ... | |
20 | 21 |
|
21 | 22 |
var storage; |
22 | 23 |
var handler; |
24 |
let policy_observable; |
|
23 | 25 |
|
24 | 26 |
function send_actions(url, port) |
25 | 27 |
{ |
26 |
const [pattern, settings] = query_best(storage, url); |
|
28 |
let [pattern, settings] = query_best(storage, url); |
|
29 |
if (!settings) |
|
30 |
settings = {allow: policy_observable && policy_observable.value}; |
|
27 | 31 |
const repos = storage.get_all(TYPE_PREFIX.REPO); |
28 | 32 |
|
29 | 33 |
port.postMessage(["settings", [pattern, settings, repos]]); |
30 | 34 |
|
31 |
if (settings === undefined) |
|
32 |
return; |
|
33 |
|
|
34 | 35 |
let components = settings.components; |
35 | 36 |
let processed_bags = new Set(); |
36 | 37 |
|
... | ... | |
127 | 128 |
storage = await get_storage(); |
128 | 129 |
|
129 | 130 |
listen_for_connection(CONNECTION_TYPE.PAGE_ACTIONS, new_connection); |
131 |
|
|
132 |
policy_observable = await light_storage.observe_var("default_allow"); |
|
130 | 133 |
} |
131 | 134 |
|
132 | 135 |
/* |
build.sh | ||
---|---|---|
291 | 291 |
cp html/*.css $BUILDDIR/html |
292 | 292 |
mkdir $BUILDDIR/icons |
293 | 293 |
cp icons/*.png $BUILDDIR/icons |
294 |
|
|
295 |
if [ "$BROWSER" = "chromium" ]; then |
|
296 |
for MOZILLA_FILE in $(find $BUILDDIR -name "MOZILLA_*"); do |
|
297 |
echo > "$MOZILLA_FILE" |
|
298 |
done |
|
299 |
fi |
|
300 |
if [ "$BROWSER" = "mozilla" ]; then |
|
301 |
for CHROMIUM_FILE in $(find $BUILDDIR -name "CHROMIUM_*"); do |
|
302 |
echo > "$CHROMIUM_FILE" |
|
303 |
done |
|
304 |
fi |
|
294 | 305 |
} |
295 | 306 |
|
296 | 307 |
main "$@" |
common/observable.js | ||
---|---|---|
6 | 6 |
* Redistribution terms are gathered in the `copyright' file. |
7 | 7 |
*/ |
8 | 8 |
|
9 |
function make() |
|
10 |
{ |
|
11 |
return new Set(); |
|
12 |
} |
|
9 |
const make = (value=undefined) => ({value, listeners: new Set()}); |
|
10 |
const subscribe = (observable, cb) => observable.listeners.add(cb); |
|
11 |
const unsubscribe = (observable, cb) => observable.listeners.delete(cb); |
|
13 | 12 |
|
14 |
function subscribe(observable, cb) |
|
15 |
{ |
|
16 |
observable.add(cb); |
|
17 |
} |
|
18 |
|
|
19 |
function unsubscribe(observable, cb) |
|
20 |
{ |
|
21 |
observable.delete(cb); |
|
22 |
} |
|
13 |
const silent_set = (observable, value) => observable.value = value; |
|
14 |
const broadcast = (observable, ...values) => |
|
15 |
observable.listeners.forEach(cb => cb(...values)); |
|
23 | 16 |
|
24 |
function broadcast(observable, event)
|
|
17 |
function set(observable, value)
|
|
25 | 18 |
{ |
26 |
for (const callback of observable) |
|
27 |
callback(event); |
|
19 |
const old_value = observable.value; |
|
20 |
silent_set(observable, value); |
|
21 |
broadcast(observable, value, old_value); |
|
28 | 22 |
} |
29 | 23 |
|
30 |
const observables = {make, subscribe, unsubscribe, broadcast}; |
|
24 |
const observables = {make, subscribe, unsubscribe, broadcast, silent_set, set};
|
|
31 | 25 |
|
32 | 26 |
/* |
33 | 27 |
* EXPORTS_START |
common/storage_light.js | ||
---|---|---|
1 |
/** |
|
2 |
* part of Hachette |
|
3 |
* Storage manager, lighter than the previous one. |
|
4 |
* |
|
5 |
* Copyright (C) 2021 Wojtek Kosior |
|
6 |
* Redistribution terms are gathered in the `copyright' file. |
|
7 |
*/ |
|
8 |
|
|
9 |
/* |
|
10 |
* IMPORTS_START |
|
11 |
* IMPORT TYPE_PREFIX |
|
12 |
* IMPORT raw_storage |
|
13 |
* IMPORT is_mozilla |
|
14 |
* IMPORT observables |
|
15 |
*/ |
|
16 |
|
|
17 |
const reg_spec = new Set(["\\", "[", "]", "(", ")", "{", "}", ".", "*", "+"]); |
|
18 |
const escape_reg_special = c => reg_spec.has(c) ? "\\" + c : c; |
|
19 |
|
|
20 |
function make_regex(name) |
|
21 |
{ |
|
22 |
return new RegExp(`^${name.split("").map(escape_reg_special).join("")}\$`); |
|
23 |
} |
|
24 |
|
|
25 |
const listeners_by_callback = new Map(); |
|
26 |
|
|
27 |
function listen(callback, prefix, name) |
|
28 |
{ |
|
29 |
let by_prefix = listeners_by_callback.get(callback); |
|
30 |
if (!by_prefix) { |
|
31 |
by_prefix = new Map(); |
|
32 |
listeners_by_callback.set(callback, by_prefix); |
|
33 |
} |
|
34 |
|
|
35 |
let by_name = by_prefix.get(prefix); |
|
36 |
if (!by_name) { |
|
37 |
by_name = new Map(); |
|
38 |
by_prefix.set(prefix, by_name); |
|
39 |
} |
|
40 |
|
|
41 |
let name_reg = by_name.get(name); |
|
42 |
if (!name_reg) { |
|
43 |
name_reg = name.test ? name : make_regex(name); |
|
44 |
by_name.set(name, name_reg); |
|
45 |
} |
|
46 |
} |
|
47 |
|
|
48 |
function no_listen(callback, prefix, name) |
|
49 |
{ |
|
50 |
const by_prefix = listeners_by_callback.get(callback); |
|
51 |
if (!by_prefix) |
|
52 |
return; |
|
53 |
|
|
54 |
const by_name = by_prefix.get(prefix); |
|
55 |
if (!by_name) |
|
56 |
return; |
|
57 |
|
|
58 |
const name_reg = by_name.get(name); |
|
59 |
if (!name_reg) |
|
60 |
return; |
|
61 |
|
|
62 |
by_name.delete(name); |
|
63 |
|
|
64 |
if (by_name.size === 0) |
|
65 |
by_prefix.delete(prefix); |
|
66 |
|
|
67 |
if (by_prefix.size === 0) |
|
68 |
listeners_by_callback.delete(callback); |
|
69 |
} |
|
70 |
|
|
71 |
function storage_change_callback(changes, area) |
|
72 |
{ |
|
73 |
if (is_mozilla && area !== "local") |
|
74 |
{console.log("area", area);return;} |
|
75 |
|
|
76 |
for (const item of Object.keys(changes)) { |
|
77 |
for (const [callback, by_prefix] of listeners_by_callback.entries()) { |
|
78 |
const by_name = by_prefix.get(item[0]); |
|
79 |
if (!by_name) |
|
80 |
continue; |
|
81 |
|
|
82 |
for (const reg of by_name.values()) { |
|
83 |
if (!reg.test(item.substring(1))) |
|
84 |
continue; |
|
85 |
|
|
86 |
try { |
|
87 |
callback(item, changes[item]); |
|
88 |
} catch(e) { |
|
89 |
console.error(e); |
|
90 |
} |
|
91 |
} |
|
92 |
} |
|
93 |
} |
|
94 |
} |
|
95 |
|
|
96 |
raw_storage.listen(storage_change_callback); |
|
97 |
|
|
98 |
|
|
99 |
const created_observables = new Map(); |
|
100 |
|
|
101 |
async function observe(prefix, name) |
|
102 |
{ |
|
103 |
const observable = observables.make(); |
|
104 |
const callback = (it, ch) => observables.set(observable, ch.newValue); |
|
105 |
listen(callback, prefix, name); |
|
106 |
created_observables.set(observable, [callback, prefix, name]); |
|
107 |
observables.silent_set(observable, await raw_storage.get(prefix + name)); |
|
108 |
|
|
109 |
return observable; |
|
110 |
} |
|
111 |
|
|
112 |
const observe_var = name => observe(TYPE_PREFIX.VAR, name); |
|
113 |
|
|
114 |
function no_observe(observable) |
|
115 |
{ |
|
116 |
no_listen(...created_observables.get(observable) || []); |
|
117 |
created_observables.delete(observable); |
|
118 |
} |
|
119 |
|
|
120 |
const light_storage = {}; |
|
121 |
Object.assign(light_storage, raw_storage); |
|
122 |
Object.assign(light_storage, |
|
123 |
{listen, no_listen, observe, observe_var, no_observe}); |
|
124 |
|
|
125 |
/* |
|
126 |
* EXPORTS_START |
|
127 |
* EXPORT light_storage |
|
128 |
* EXPORTS_END |
|
129 |
*/ |
common/storage_raw.js | ||
---|---|---|
26 | 26 |
|
27 | 27 |
async function set(key_or_object, value) |
28 | 28 |
{ |
29 |
return browser.storage.local.set(typeof key_or_object === "object" ? |
|
30 |
key_or_object : {[key]: value}); |
|
29 |
const arg = typeof key_or_object === "object" ? |
|
30 |
key_or_object : {[key_or_object]: value}; |
|
31 |
return browser.storage.local.set(arg); |
|
31 | 32 |
} |
32 | 33 |
|
33 | 34 |
async function set_var(name, value) |
... | ... | |
40 | 41 |
return get(TYPE_PREFIX.VAR + name); |
41 | 42 |
} |
42 | 43 |
|
43 |
const raw_storage = {get, set, get_var, set_var}; |
|
44 |
const on_changed = browser.storage.onChanged || browser.storage.local.onChanged; |
|
45 |
const listen = cb => on_changed.addListener(cb); |
|
46 |
const no_listen = cb => on_changed.removeListener(cb); |
|
47 |
|
|
48 |
const raw_storage = {get, set, get_var, set_var, listen, no_listen}; |
|
44 | 49 |
|
45 | 50 |
/* |
46 | 51 |
* EXPORTS_START |
content/main.js | ||
---|---|---|
123 | 123 |
} |
124 | 124 |
|
125 | 125 |
if (!policy) { |
126 |
console.warn("Using default policy!");
|
|
126 |
console.warn("Using fallback policy!");
|
|
127 | 127 |
policy = {allow: false, nonce: gen_nonce()}; |
128 | 128 |
} |
129 | 129 |
|
content/page_actions.js | ||
---|---|---|
36 | 36 |
} |
37 | 37 |
if (action === "settings") { |
38 | 38 |
report_settings(data); |
39 |
policy_received_callback({url, allow: !!data[1] && data[1].allow});
|
|
39 |
policy_received_callback({url, allow: data[1].allow}); |
|
40 | 40 |
} |
41 | 41 |
} |
42 | 42 |
|
html/MOZILLA_scrollbar_fix.css | ||
---|---|---|
1 |
/** |
|
2 |
* Hachette |
|
3 |
* Hacky fix for vertical scrollbar width being included in child's width. |
|
4 |
* |
|
5 |
* Copyright (C) 2021 Wojtek Kosior |
|
6 |
* Redistribution terms are gathered in the `copyright' file. |
|
7 |
*/ |
|
8 |
|
|
9 |
/* |
|
10 |
* Under Mozilla browsers to avoid vertical scrollbar forcing horizontal |
|
11 |
* scrollbar to appear in an element we add the `firefox_scrollbars_hacky_fix' |
|
12 |
* class to an element for which width has to be reserved. |
|
13 |
* |
|
14 |
* This is a bit hacky and relies on some assumed width of Firefox scrollbar, I |
|
15 |
* know. And must be excluded from Chromium builds. |
|
16 |
* |
|
17 |
* I came up with this hack when working on popup. Before that I had the |
|
18 |
* scrollbar issue with tables in the options page and gave up there and made |
|
19 |
* the scrollbal always visible. Now we could try applying this "fix" there, |
|
20 |
* too! |
|
21 |
*/ |
|
22 |
|
|
23 |
.firefox_scrollbars_hacky_fix { |
|
24 |
font-size: 0; |
|
25 |
} |
|
26 |
|
|
27 |
.firefox_scrollbars_hacky_fix>div { |
|
28 |
display: inline-block; |
|
29 |
width: -moz-available; |
|
30 |
} |
|
31 |
|
|
32 |
.firefox_scrollbars_hacky_fix>*>* { |
|
33 |
font-size: initial; |
|
34 |
} |
|
35 |
|
|
36 |
.firefox_scrollbars_hacky_fix::after { |
|
37 |
content: ""; |
|
38 |
display: inline-block; |
|
39 |
visibility: hidden; |
|
40 |
font-size: initial; |
|
41 |
width: 14px; |
|
42 |
} |
|
43 |
|
|
44 |
.firefox_scrollbars_hacky_fix.has_inline_content::after { |
|
45 |
width: calc(14px - 0.3em); |
|
46 |
} |
html/base.css | ||
---|---|---|
100 | 100 |
background: linear-gradient(#555, transparent); |
101 | 101 |
} |
102 | 102 |
|
103 |
.has_bottom_thin_line { |
|
104 |
border-bottom: dashed #4CAF50 1px; |
|
105 |
} |
|
106 |
|
|
107 |
.has_upper_thin_line { |
|
108 |
border-top: dashed #4CAF50 1px; |
|
109 |
} |
|
110 |
|
|
103 | 111 |
.nowrap { |
104 | 112 |
white-space: nowrap; |
105 | 113 |
} |
html/default_blocking_policy.html | ||
---|---|---|
1 |
<!-- |
|
2 |
Copyright (C) 2021 Wojtek Kosior |
|
3 |
Redistribution terms are gathered in the `copyright' file. |
|
4 |
|
|
5 |
This is not a standalone page. This file is meant to be imported into other |
|
6 |
HTML code. |
|
7 |
--> |
|
8 |
<style> |
|
9 |
#blocking_policy_div { |
|
10 |
line-height: 2em; |
|
11 |
} |
|
12 |
</style> |
|
13 |
<span id="blocking_policy_span"> |
|
14 |
Default policy for unmatched pages is to |
|
15 |
<span id="current_policy_span" class="bold"></span> |
|
16 |
their own scripts. |
|
17 |
<button id="toggle_policy_but">Toggle policy</button> |
|
18 |
</span> |
html/default_blocking_policy.js | ||
---|---|---|
1 |
/** |
|
2 |
* part of Hachette |
|
3 |
* Default policy dialog logic. |
|
4 |
* |
|
5 |
* Copyright (C) 2021 Wojtek Kosior |
|
6 |
* Redistribution terms are gathered in the `copyright' file. |
|
7 |
*/ |
|
8 |
|
|
9 |
/* |
|
10 |
* IMPORTS_START |
|
11 |
* IMPORT by_id |
|
12 |
* IMPORT light_storage |
|
13 |
* IMPORT observables |
|
14 |
* IMPORTS_END |
|
15 |
*/ |
|
16 |
|
|
17 |
/* |
|
18 |
* Used with `default_blocking_policy.html' to allow user to choose whether to |
|
19 |
* block scripts globally or not. |
|
20 |
*/ |
|
21 |
|
|
22 |
const blocking_policy_span = by_id("blocking_policy_span"); |
|
23 |
const current_policy_span = by_id("current_policy_span"); |
|
24 |
const toggle_policy_but = by_id("toggle_policy_but"); |
|
25 |
|
|
26 |
let policy_observable; |
|
27 |
|
|
28 |
const update_policy = |
|
29 |
allowed => current_policy_span.textContent = allowed ? "allow" : "block"; |
|
30 |
const toggle_policy = |
|
31 |
() => light_storage.set_var("default_allow", !policy_observable.value); |
|
32 |
|
|
33 |
async function init_default_policy_dialog() |
|
34 |
{ |
|
35 |
policy_observable = await light_storage.observe_var("default_allow"); |
|
36 |
update_policy(policy_observable.value); |
|
37 |
observables.subscribe(policy_observable, update_policy); |
|
38 |
|
|
39 |
toggle_policy_but.addEventListener("click", toggle_policy); |
|
40 |
blocking_policy_span.classList.remove("hide"); |
|
41 |
} |
|
42 |
|
|
43 |
/* |
|
44 |
* EXPORTS_START |
|
45 |
* EXPORT init_default_policy_dialog |
|
46 |
* EXPORTS_END |
|
47 |
*/ |
html/display-panel.html | ||
---|---|---|
11 | 11 |
<link type="text/css" rel="stylesheet" href="base.css" /> |
12 | 12 |
<link type="text/css" rel="stylesheet" href="back_button.css" /> |
13 | 13 |
<link type="text/css" rel="stylesheet" href="table.css" /> |
14 |
<link type="text/css" rel="stylesheet" href="MOZILLA_scrollbar_fix.css" /> |
|
14 | 15 |
<style> |
15 | 16 |
body { |
16 | 17 |
width: max-content; |
17 |
width: -moz-max-content;
|
|
18 |
width: -moz-fit-content;
|
|
18 | 19 |
} |
19 | 20 |
|
20 | 21 |
.top>h2 { |
... | ... | |
114 | 115 |
pre { |
115 | 116 |
font-family: monospace; |
116 | 117 |
background-color: white; |
117 |
border-top: dashed #4CAF50 1px; |
|
118 |
border-bottom: dashed #4CAF50 1px; |
|
119 | 118 |
padding: 1px 5px; |
120 | 119 |
} |
121 | 120 |
|
... | ... | |
133 | 132 |
padding-right: 5px; |
134 | 133 |
} |
135 | 134 |
|
135 |
.padding_top { |
|
136 |
padding-top: 5px; |
|
137 |
} |
|
138 |
|
|
136 | 139 |
.header { |
137 |
border-bottom: dashed #4CAF50 1px; |
|
138 | 140 |
padding-bottom: 0.3em; |
139 | 141 |
margin-bottom: 0.5em; |
140 | 142 |
text-align: center; |
... | ... | |
146 | 148 |
} |
147 | 149 |
|
148 | 150 |
.footer { |
149 |
border-top: dashed #4CAF50 1px; |
|
150 | 151 |
padding-top: 0.3em; |
151 | 152 |
margin-top: 0.5em; |
152 | 153 |
text-align: center; |
... | ... | |
199 | 200 |
<label data-template="lbl"> |
200 | 201 |
<h3><div class="unroll_triangle"></div> script</h3> |
201 | 202 |
</label> |
202 |
<pre data-template="script_contents"></pre> |
|
203 |
<pre class="has_bottom_thin_line has_upper_thin_line" data-template="script_contents"></pre>
|
|
203 | 204 |
</div> |
204 | 205 |
</div> |
205 | 206 |
|
... | ... | |
242 | 243 |
Patterns higher are more specific and override the ones below. |
243 | 244 |
</aside> |
244 | 245 |
</div> |
245 |
<div class="table_wrapper"> |
|
246 |
<div class="table_wrapper firefox_scrollbars_hacky_fix">
|
|
246 | 247 |
<div> |
247 | 248 |
<table> |
248 | 249 |
<tbody id="possible_patterns"> |
... | ... | |
250 | 251 |
</table> |
251 | 252 |
</div> |
252 | 253 |
</div> |
254 |
<div class="padding_inline padding_top has_upper_thin_line firefox_scrollbars_hacky_fix has_inline_content"> |
|
255 |
<span class="nowrap"> |
|
256 |
<IMPORT html/default_blocking_policy.html /> |
|
257 |
</span> |
|
258 |
</div> |
|
253 | 259 |
</div> |
254 | 260 |
|
255 | 261 |
<input id="show_queried_view_radio" type="radio" class="show_next" name="current_view"></input> |
... | ... | |
265 | 271 |
<h3 id="privileged_notice" class="middle hide">Privileged page</h3> |
266 | 272 |
|
267 | 273 |
<div id="page_state" class="hide"> |
268 |
<div class="header padding_inline"> |
|
274 |
<div class="header padding_inline has_bottom_thin_line">
|
|
269 | 275 |
<label for="show_patterns_view_radio" class="button"> |
270 | 276 |
Edit settings for this page |
271 | 277 |
</label> |
... | ... | |
317 | 323 |
</div> |
318 | 324 |
</div> |
319 | 325 |
|
320 |
<div class="footer padding_inline"> |
|
326 |
<div class="footer padding_inline has_upper_thin_line">
|
|
321 | 327 |
<button id="settings_but" type="button"> |
322 | 328 |
Open Hachette settings |
323 | 329 |
</button> |
html/display-panel.js | ||
---|---|---|
14 | 14 |
*** temporarily, before all storage access gets reworked. |
15 | 15 |
* IMPORT get_remote_storage |
16 | 16 |
* IMPORT get_import_frame |
17 |
* IMPORT init_default_policy_dialog |
|
17 | 18 |
* IMPORT query_all |
18 | 19 |
* IMPORT CONNECTION_TYPE |
19 | 20 |
* IMPORT is_privileged_url |
... | ... | |
243 | 244 |
if (type === "settings") { |
244 | 245 |
let [pattern, settings] = data; |
245 | 246 |
|
246 |
settings = settings || {}; |
|
247 | 247 |
blocked_span.textContent = settings.allow ? "no" : "yes"; |
248 | 248 |
|
249 | 249 |
if (pattern) { |
... | ... | |
254 | 254 |
view_pattern_but.addEventListener("click", settings_opener); |
255 | 255 |
} else { |
256 | 256 |
pattern_span.textContent = "none"; |
257 |
blocked_span.textContent = blocked_span.textContent + " (default)"; |
|
257 | 258 |
} |
258 | 259 |
|
259 | 260 |
const components = settings.components; |
... | ... | |
549 | 550 |
|
550 | 551 |
async function main() |
551 | 552 |
{ |
553 |
init_default_policy_dialog(); |
|
554 |
|
|
552 | 555 |
storage = await get_remote_storage(); |
553 | 556 |
import_frame = await get_import_frame(); |
554 | 557 |
import_frame.onclose = () => show_queried_view_radio.checked = true; |
html/import_frame.html | ||
---|---|---|
1 |
<!-- |
|
2 |
Copyright (C) 2021 Wojtek Kosior |
|
3 |
Redistribution terms are gathered in the `copyright' file. |
|
4 |
|
|
5 |
This is not a standalone page. This file is meant to be imported into other |
|
6 |
HTML code. |
|
7 |
--> |
|
1 | 8 |
<style> |
2 | 9 |
.padding_right { |
3 | 10 |
padding-right: 0.3em; |
html/options.html | ||
---|---|---|
248 | 248 |
</div> |
249 | 249 |
</div> |
250 | 250 |
<button id="add_page_but" type="button"> Add page </button> |
251 |
<IMPORT html/default_blocking_policy.html /> |
|
251 | 252 |
</div> |
252 | 253 |
<div id="bags" class="tab"> |
253 | 254 |
<div class="table_wrapper tight_table has_bottom_line has_upper_line"> |
html/options_main.js | ||
---|---|---|
17 | 17 |
* IMPORT by_id |
18 | 18 |
* IMPORT matchers |
19 | 19 |
* IMPORT get_import_frame |
20 |
* IMPORT init_default_policy_dialog |
|
20 | 21 |
* IMPORTS_END |
21 | 22 |
*/ |
22 | 23 |
|
... | ... | |
670 | 671 |
|
671 | 672 |
async function main() |
672 | 673 |
{ |
674 |
init_default_policy_dialog(); |
|
675 |
|
|
673 | 676 |
storage = await get_remote_storage(); |
674 | 677 |
|
675 | 678 |
for (let prefix of list_prefixes) { |
Also available in: Unified diff
enable toggling of global script blocking policy\n\nThis commit also introduces `light_storage' module which is later going to replace the storage code we use right now.\nAlso included is a hack to properly display scrollbars under Mozilla (needs testing on newer Mozilla browsers).