Project

General

Profile

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

haketilo / html / item_preview.js @ 4c6a2323

1
/**
2
 * This file is part of Haketilo.
3
 *
4
 * Function: Showing resource/mapping details in a browser.
5
 *
6
 * Copyright (C) 2022 Wojtek Kosior
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * As additional permission under GNU GPL version 3 section 7, you
19
 * may distribute forms of that code without the copy of the GNU
20
 * GPL normally required by section 4, provided you include this
21
 * license notice and, in case of non-source distribution, a URL
22
 * through which recipients can access the Corresponding Source.
23
 * If you modify file(s) with this exception, you may extend this
24
 * exception to your version of the file(s), but you are not
25
 * obligated to do so. If you do not wish to do so, delete this
26
 * exception statement from your version.
27
 *
28
 * As a special exception to the GPL, any HTML file which merely
29
 * makes function calls to this code, and for that purpose
30
 * includes it by reference shall be deemed a separate work for
31
 * copyright law purposes. If you modify this code, you may extend
32
 * this exception to your version of the code, but you are not
33
 * obligated to do so. If you do not wish to do so, delete this
34
 * exception statement from your version.
35
 *
36
 * You should have received a copy of the GNU General Public License
37
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
38
 *
39
 * I, Wojtek Kosior, thereby promise not to sue for violation of this file's
40
 * license. Although I request that you do not make use of this code in a
41
 * proprietary program, I am not going to enforce this in court.
42
 */
43

    
44
#IMPORT common/indexeddb.js AS haketilodb
45
#IMPORT html/dialog.js
46

    
47
#FROM html/DOM_helpers.js IMPORT clone_template
48

    
49
function populate_list(ul, items)
50
{
51
    for (const item of items) {
52
	const li = document.createElement("li");
53
	li.append(item);
54
	ul.append(li);
55
    }
56
}
57

    
58
/* Link click handler used in make_file_link(). */
59
async function file_link_clicked(preview_object, file_ref, event)
60
{
61
    event.preventDefault();
62

    
63
    const db = await haketilodb.get();
64
    const file = await haketilodb.idb_get(db.transaction("files"),
65
					  "files", file_ref.hash_key);
66
    if (file === undefined) {
67
	dialog.error(preview_object.dialog_context,
68
		     "File missing from Haketilo's internal database :(");
69
    } else {
70
	const encoded_file = encodeURIComponent(file.contents);
71
	open(`data:text/plain;charset=utf8,${encoded_file}`, '_blank');
72
    }
73
}
74

    
75
/*
76
 * The default function to use to create file preview link. Links it creates can
77
 * be used to view files from IndexedDB.
78
 */
79
function make_file_link(preview_object, file_ref)
80
{
81
    const a = document.createElement("a");
82
    a.href = "javascript:void(0)";
83
    a.innerText = file_ref.file;
84
    a.addEventListener("click",
85
		       e => file_link_clicked(preview_object, file_ref, e));
86

    
87
    return a;
88
}
89

    
90
function resource_preview(resource, preview_object, dialog_context,
91
			  make_link_cb=make_file_link)
92
{
93
    if (preview_object === undefined)
94
	preview_object = clone_template("resource_preview");
95

    
96
    preview_object.identifier.innerText  = resource.identifier;
97
    preview_object.long_name.innerText   = resource.long_name;
98
    preview_object.uuid.innerText        = resource.uuid;
99
    preview_object.version.innerText     =
100
	`${resource.version.join(".")}-${resource.revision}`;
101
    preview_object.description.innerText = resource.description;
102
    preview_object.source_name.innerText = resource.source_name;
103

    
104
    [...preview_object.dependencies.childNodes].forEach(n => n.remove());
105
    populate_list(preview_object.dependencies, resource.dependencies);
106

    
107
    const link_maker = file_ref => make_link_cb(preview_object, file_ref);
108

    
109
    [...preview_object.scripts.childNodes].forEach(n => n.remove());
110
    populate_list(preview_object.scripts, resource.scripts.map(link_maker));
111

    
112
    [...preview_object.copyright.childNodes].forEach(n => n.remove());
113
    populate_list(preview_object.copyright,
114
		  resource.source_copyright.map(link_maker));
115

    
116
    preview_object.dialog_context = dialog_context;
117

    
118
    return preview_object;
119
}
120
#EXPORT resource_preview
121

    
122
function mapping_preview(mapping, preview_object, dialog_context,
123
			 make_link_cb=make_file_link)
124
{
125
    if (preview_object === undefined)
126
	preview_object = clone_template("mapping_preview");
127

    
128
    preview_object.identifier.innerText  = mapping.identifier;
129
    preview_object.long_name.innerText   = mapping.long_name;
130
    preview_object.uuid.innerText        = mapping.uuid;
131
    preview_object.version.innerText     = mapping.version.join(".");
132
    preview_object.description.innerText = mapping.description;
133
    preview_object.source_name.innerText = mapping.source_name;
134

    
135
    [...preview_object.payloads.childNodes].forEach(n => n.remove());
136
    for (const [pattern, payload] of Object.entries(mapping.payloads).sort()) {
137
	/* We use a non-breaking space because normal space would be ignored. */
138
	const [nbsp, rarrow] = [160, 0x2192].map(n => String.fromCodePoint(n));
139
	const texts = [`${pattern}${nbsp}`, `${rarrow}  ${payload.identifier}`];
140
	for (let i = 0; i < texts.length; i++) {
141
	    const span = document.createElement("span");
142
	    span.innerText = texts[i];
143
	    span.classList.add(`grid_col_${i + 1}`);
144
	    preview_object.payloads.append(span);
145
	}
146
    }
147

    
148
    const link_maker = file_ref => make_link_cb(preview_object, file_ref);
149

    
150
    [...preview_object.copyright.childNodes].forEach(n => n.remove());
151
    populate_list(preview_object.copyright,
152
		  mapping.source_copyright.map(link_maker));
153

    
154
    preview_object.dialog_context = dialog_context;
155

    
156
    return preview_object;
157
}
158
#EXPORT mapping_preview
(13-13/24)