Project

General

Profile

« Previous | Next » 

Revision 453ba039

Added by koszko about 2 years ago

add styling for popup page\n\nThis does not include styling for contents of the import dialog

View differences:

html/display-panel.js
20 20
 * IMPORT TYPE_PREFIX
21 21
 * IMPORT nice_name
22 22
 * IMPORT open_in_settings
23
 * IMPORT url_matches
23 24
 * IMPORT each_url_pattern
24 25
 * IMPORT by_id
25 26
 * IMPORT get_template
......
30 31
let storage;
31 32
let tab_url;
32 33

  
34
/* Force popup <html>'s reflow on stupid Firefox. */
35
if (is_mozilla) {
36
    const reflow_forcer =
37
	  () => document.documentElement.style.width = "-moz-fit-content";
38
    for (const radio of document.querySelectorAll('[name="current_view"]'))
39
	radio.addEventListener("change", reflow_forcer);
40
}
41

  
42
const show_queried_view_radio = by_id("show_queried_view_radio");
43

  
33 44
const tab_query = {currentWindow: true, active: true};
34 45

  
35 46
async function get_current_tab()
......
48 59
}
49 60

  
50 61
const page_url_heading = by_id("page_url_heading");
51
const show_privileged_notice_chbx = by_id("show_privileged_notice_chbx");
52
const show_page_state_chbx = by_id("show_page_state_chbx");
62
const privileged_notice = by_id("privileged_notice");
63
const page_state = by_id("page_state");
64

  
65
/* Helper functions to convert string into a list of one-letter <span>'s. */
66
function char_to_span(char, doc)
67
{
68
    const span = document.createElement("span");
69
    span.textContent = char;
70
    return span;
71
}
72

  
73
function to_spans(string, doc=document)
74
{
75
    return string.split("").map(c => char_to_span(c, doc));
76
}
53 77

  
54 78
async function show_page_activity_info()
55 79
{
......
61 85
    }
62 86

  
63 87
    tab_url = /^([^?#]*)/.exec(tab.url)[1];
64
    page_url_heading.textContent = tab_url;
88
    to_spans(tab_url).forEach(s => page_url_heading.append(s));
65 89
    if (is_privileged_url(tab_url)) {
66
	show_privileged_notice_chbx.checked = true;
90
	privileged_notice.classList.remove("hide");
67 91
	return;
68 92
    }
69 93

  
70 94
    populate_possible_patterns_list(tab_url);
71
    show_page_state_chbx.checked = true;
95
    page_state.classList.remove("hide");
72 96

  
73 97
    try_to_connect(tab.id);
74 98
}
75 99

  
76
const possible_patterns_ul = by_id("possible_patterns");
77
const pattern_li_template = get_template("pattern_li");
78
pattern_li_template.removeAttribute("id");
100
const possible_patterns_list = by_id("possible_patterns");
79 101
const known_patterns = new Map();
80 102

  
81 103
function add_pattern_to_list(pattern)
82 104
{
83
    const li = pattern_li_template.cloneNode(true);
84
    li.id = `pattern_li_${known_patterns.size}`;
85
    known_patterns.set(pattern, li.id);
105
    const template = clone_template("pattern_entry");
106
    template.name.textContent = pattern;
86 107

  
87
    const span = li.firstElementChild;
88
    span.textContent = pattern;
89

  
90
    const button = span.nextElementSibling;
91 108
    const settings_opener = () => open_in_settings(TYPE_PREFIX.PAGE, pattern);
92
    button.addEventListener("click", settings_opener);
109
    template.button.addEventListener("click", settings_opener);
93 110

  
94
    possible_patterns_ul.appendChild(li)
111
    known_patterns.set(pattern, template);
112
    possible_patterns_list.append(template.entry);
95 113

  
96
    return li.id;
114
    return template;
97 115
}
98 116

  
99 117
function ensure_pattern_exists(pattern)
100 118
{
101
    let id = known_patterns.get(pattern);
119
    let entry_object = known_patterns.get(pattern);
102 120
    /*
103 121
     * As long as pattern computation works well, we should never get into this
104 122
     * conditional block. This is just a safety measure. To be removed as part
105 123
     * of a bigger rework when we start taking iframes into account.
106 124
     */
107
    if (id === undefined) {
125
    if (entry_object === undefined) {
108 126
	console.log(`unknown pattern: ${pattern}`);
109
	id = add_pattern_to_list(pattern);
127
	entry_object = add_pattern_to_list(pattern);
110 128
    }
111 129

  
112
    return id;
130
    return entry_object;
113 131
}
114 132

  
115
function set_pattern_li_button_text(li_id, text)
133
function style_possible_pattern_entry(pattern, exists_in_settings)
116 134
{
117
    by_id(li_id).firstElementChild.nextElementSibling.textContent = text;
135
    const [text, class_action] = exists_in_settings ?
136
	  ["Edit", "add"] : ["Add", "remove"];
137
    const entry_object = ensure_pattern_exists(pattern);
138

  
139
    entry_object.button.textContent = `${text} setting`;
140
    entry_object.entry.classList[class_action]("matched_pattern");
118 141
}
119 142

  
120 143
function handle_page_change(change)
121 144
{
122
    const li_id = ensure_pattern_exists(change.item);
123
    if (change.old_val === undefined)
124
	set_pattern_li_button_text(li_id, "Edit in settings");
125
    if (change.new_val === undefined)
126
	set_pattern_li_button_text(li_id, "Add setting");
145
    if (url_matches(tab_url, change.item))
146
        style_possible_pattern_entry(change.item, change.new_val !== undefined);
127 147
}
128 148

  
129 149
function populate_possible_patterns_list(url)
......
131 151
    for (const pattern of each_url_pattern(url))
132 152
	add_pattern_to_list(pattern);
133 153

  
134
    for (const [pattern, settings] of query_all(storage, url)) {
135
	set_pattern_li_button_text(ensure_pattern_exists(pattern),
136
				   "Edit in settings");
137
    }
154
    for (const [pattern, settings] of query_all(storage, url))
155
	style_possible_pattern_entry(pattern, true);
138 156

  
139 157
    storage.add_change_listener(handle_page_change, [TYPE_PREFIX.PAGE]);
140 158
}
......
160 178
	setTimeout(() => monitor_connecting(tab_id), 1000);
161 179
}
162 180

  
163
const query_started_chbx = by_id("query_started_chbx");
164

  
165
function start_querying_repos(port)
181
function start_querying_repos()
166 182
{
183
    query_pattern_but.removeEventListener("click", start_querying_repos);
167 184
    const repo_urls = storage.get_all_names(TYPE_PREFIX.REPO);
168 185
    if (content_script_port)
169 186
	content_script_port.postMessage([TYPE_PREFIX.URL, tab_url, repo_urls]);
170
    query_started_chbx.checked = true;
171 187
}
172 188

  
173
const loading_chbx = by_id("loading_chbx");
189
const loading_point = by_id("loading_point");
190
const reload_notice = by_id("reload_notice");
174 191

  
175 192
function handle_disconnect(tab_id, button_cb)
176 193
{
......
184 201
    if (connected_chbx.checked)
185 202
	return;
186 203

  
187
    loading_chbx.checked = !loading_chbx.checked;
204
    loading_point.classList.toggle("camouflage");
205
    reload_notice.classList.remove("hide");
206

  
188 207
    setTimeout(() => try_to_connect(tab_id), 1000);
189 208
}
190 209

  
......
198 217
    else
199 218
	return;
200 219

  
201
    loading_chbx.checked = !loading_chbx.checked;
220
    loading_point.classList.toggle("camouflage");
221
    reload_notice.classList.remove("hide");
202 222
    try_to_connect(tab_id);
203 223
}
204 224

  
......
206 226
const view_pattern_but = by_id("view_pattern");
207 227
const blocked_span = by_id("blocked");
208 228
const payload_span = by_id("payload");
229
const payload_buttons_div = by_id("payload_buttons");
209 230
const view_payload_but = by_id("view_payload");
231
const view_injected_but = by_id("view_injected");
210 232
const container_for_injected = by_id("container_for_injected");
211 233

  
212 234
const queried_items = new Map();
213 235

  
236
let max_injected_script_id = 0;
237

  
214 238
function handle_activity_report(message)
215 239
{
216 240
    connected_chbx.checked = true;
......
236 260
	const components = settings.components;
237 261
	if (components) {
238 262
	    payload_span.textContent = nice_name(...components);
263
	    payload_buttons_div.classList.remove("hide");
239 264
	    const settings_opener = () => open_in_settings(...components);
240
	    view_payload_but.classList.remove("hide");
241 265
	    view_payload_but.addEventListener("click", settings_opener);
242 266
	} else {
243 267
	    payload_span.textContent = "none";
244 268
	}
245 269
    }
246 270
    if (type === "script") {
247
	const h4 = document.createElement("h4");
248
	const pre = document.createElement("pre");
249
	h4.textContent = "script";
250
	pre.textContent = data;
251

  
252
	container_for_injected.appendChild(h4);
253
	container_for_injected.appendChild(pre);
271
	const template = clone_template("injected_script");
272
	const chbx_id = `injected_script_${max_injected_script_id++}`;
273
	template.chbx.id = chbx_id;
274
	template.lbl.setAttribute("for", chbx_id);
275
	template.script_contents.textContent = data;
276
	container_for_injected.appendChild(template.div);
254 277
    }
255 278
    if (type === "repo_query_action") {
256
	query_started_chbx.checked = true;
257

  
258 279
	const key = data.prefix + data.item;
259 280
	const results = queried_items.get(key) || {};
260 281
	Object.assign(results, data.results);
......
274 295

  
275 296
function create_results_list(url)
276 297
{
277
    const list_div = document.createElement("div");
278
    const list_head = document.createElement("h4");
279
    const list = document.createElement("ul");
298
    const cloned_template = clone_template("multi_repos_query_result");
299
    cloned_template.url_span.textContent = url;
300
    container_for_repo_responses.appendChild(cloned_template.div);
280 301

  
281
    list_head.textContent = url;
282
    list_div.appendChild(list_head);
283
    list_div.appendChild(list);
284
    container_for_repo_responses.appendChild(list_div);
302
    cloned_template.by_repo = new Map();
303
    results_lists.set(url, cloned_template);
285 304

  
286
    const list_object = {list, by_repo: new Map()};
287

  
288
    results_lists.set(url, list_object);
289

  
290
    return list_object;
305
    return cloned_template;
291 306
}
292 307

  
293 308
function create_result_item(list_object, repo_url, result)
294 309
{
295
    const result_li = document.createElement("li");
296
    const repo_url_span = document.createElement("span");
297
    const result_item = {result_li, appended: null};
298

  
299
    repo_url_span.textContent = repo_url;
300
    result_li.appendChild(repo_url_span);
310
    const cloned_template = clone_template("single_repo_query_result");
311
    cloned_template.repo_url.textContent = repo_url;
312
    cloned_template.appended = null;
301 313

  
302
    list_object.list.appendChild(result_li);
303
    list_object.by_repo.set(repo_url, result_item);
314
    list_object.ul.appendChild(cloned_template.li);
315
    list_object.by_repo.set(repo_url, cloned_template);
304 316

  
305
    return result_item;
317
    return cloned_template;
306 318
}
307 319

  
308 320
function set_appended(result_item, element)
......
310 322
    if (result_item.appended)
311 323
	result_item.appended.remove();
312 324
    result_item.appended = element;
313
    result_item.result_li.appendChild(element);
325
    result_item.li.appendChild(element);
314 326
}
315 327

  
316 328
function show_message(result_item, text)
......
333 345
    entry_object.chbx.removeEventListener("change", entry_object.unroll_cb);
334 346
    delete entry_object.unroll_cb;
335 347

  
336
    entry_object.unroll.textContent = "preview not implemented...";
348
    entry_object.unroll.innerHTML = "preview not implemented...<br />(consider contributing)";
337 349
}
338 350

  
339
const show_install_chbx = by_id("show_install_view_chbx");
340

  
341 351
let import_frame;
342 352
let install_target = null;
343 353

  
......
463 473

  
464 474
function install_clicked(entry_object)
465 475
{
466
    show_install_chbx.checked = true;
467 476
    import_frame.show_loading();
468 477

  
469 478
    install_target = {
......
483 492

  
484 493
function show_query_successful_result(result_item, repo_url, result)
485 494
{
486
    const ul = document.createElement("ul");
487

  
488
    set_appended(result_item, ul);
495
    const cloned_ul_template = clone_template("result_patterns_list");
496
    set_appended(result_item, cloned_ul_template.ul);
489 497

  
490 498
    for (const match of result) {
491 499
	const entry_object = clone_template("query_match_li");
492 500

  
493 501
	entry_object.pattern.textContent = match.pattern;
494 502

  
495
	ul.appendChild(entry_object.li);
503
	cloned_ul_template.ul.appendChild(entry_object.li);
496 504

  
497 505
	if (!match.payload) {
498 506
	    entry_object.payload.textContent = "(none)";
499
	    for (const key of ["chbx", "br", "triangle", "unroll"])
507
	    for (const key of ["chbx", "triangle", "unroll"])
500 508
		entry_object[key].remove();
501 509
	    continue;
502 510
	}
503 511

  
504
	entry_object.component.textContent = nice_name(...match.payload);
512
	entry_object.payload.textContent = nice_name(...match.payload);
505 513

  
506 514
	const install_cb = () => install_clicked(entry_object);
507 515
	entry_object.btn.addEventListener("click", install_cb);
......
544 552
{
545 553
    storage = await get_remote_storage();
546 554
    import_frame = await get_import_frame();
547
    import_frame.onclose = () => show_install_chbx.checked = false;
555
    import_frame.onclose = () => show_queried_view_radio.checked = true;
548 556
    show_page_activity_info();
549 557
}
550 558

  

Also available in: Unified diff