diff options
Diffstat (limited to 'html/item_preview.js')
-rw-r--r-- | html/item_preview.js | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/html/item_preview.js b/html/item_preview.js new file mode 100644 index 0000000..f59e30e --- /dev/null +++ b/html/item_preview.js @@ -0,0 +1,151 @@ +/** + * This file is part of Haketilo. + * + * Function: Showing resource/mapping details in a browser. + * + * Copyright (C) 2022 Wojtek Kosior + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * As additional permission under GNU GPL version 3 section 7, you + * may distribute forms of that code without the copy of the GNU + * GPL normally required by section 4, provided you include this + * license notice and, in case of non-source distribution, a URL + * through which recipients can access the Corresponding Source. + * If you modify file(s) with this exception, you may extend this + * exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * As a special exception to the GPL, any HTML file which merely + * makes function calls to this code, and for that purpose + * includes it by reference shall be deemed a separate work for + * copyright law purposes. If you modify this code, you may extend + * this exception to your version of the code, but you are not + * obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + * I, Wojtek Kosior, thereby promise not to sue for violation of this file's + * license. Although I request that you do not make use of this code in a + * proprietary program, I am not going to enforce this in court. + */ + +#IMPORT common/indexeddb.js AS haketilodb +#IMPORT html/dialog.js + +#FROM html/DOM_helpers.js IMPORT clone_template + +function populate_list(ul, items) +{ + for (const item of items) { + const li = document.createElement("li"); + li.append(item); + ul.append(li); + } +} + +async function file_link_clicked(preview_object, file_ref, event) +{ + event.preventDefault(); + + const db = await haketilodb.get(); + const file = await haketilodb.idb_get(db.transaction("files"), + "files", file_ref.hash_key); + if (file === undefined) { + dialog.error(preview_object.dialog_context, + "File missing from Haketilo's inernal database :("); + } else { + const encoded_file = encodeURIComponent(file.contents); + open(`data:text/plain;charset=utf8,${encoded_file}`, '_blank'); + } +} + +function make_file_link(preview_object, file_ref) +{ + const a = document.createElement("a"); + a.href = "javascript:void(0)"; + a.innerText = file_ref.file; + a.addEventListener("click", + e => file_link_clicked(preview_object, file_ref, e)); + + return a; +} + +function resource_preview(resource, preview_object, dialog_context) +{ + if (preview_object === undefined) + preview_object = clone_template("resource_preview_div"); + + preview_object.identifier.innerText = resource.identifier; + preview_object.long_name.innerText = resource.long_name; + preview_object.uuid.innerText = resource.uuid; + preview_object.version.innerText = + `${resource.version.join(".")}-${resource.revision}`; + preview_object.description.innerText = resource.description; + preview_object.source_name.innerText = resource.source_name; + + [...preview_object.dependencies.childNodes].forEach(n => n.remove()); + populate_list(preview_object.dependencies, resource.dependencies); + + const link_maker = file_ref => make_file_link(preview_object, file_ref); + + [...preview_object.scripts.childNodes].forEach(n => n.remove()); + populate_list(preview_object.scripts, resource.scripts.map(link_maker)); + + [...preview_object.copyright.childNodes].forEach(n => n.remove()); + populate_list(preview_object.copyright, + resource.source_copyright.map(link_maker)); + + preview_object.dialog_context = dialog_context; + + return preview_object; +} +#EXPORT resource_preview + +function mapping_preview(mapping, preview_object, dialog_context) +{ + if (preview_object === undefined) + preview_object = clone_template("mapping_preview_div"); + + preview_object.identifier.innerText = mapping.identifier; + preview_object.long_name.innerText = mapping.long_name; + preview_object.uuid.innerText = mapping.uuid; + preview_object.version.innerText = mapping.version.join("."); + preview_object.description.innerText = mapping.description; + preview_object.source_name.innerText = mapping.source_name; + + [...preview_object.payloads.childNodes].forEach(n => n.remove()); + for (const [pattern, payload] of Object.entries(mapping.payloads).sort()) { + /* We use a non-breaking space because normal space would be ignored. */ + const [nbsp, rarrow] = [160, 0x2192].map(n => String.fromCodePoint(n)); + const texts = [`${pattern}${nbsp}`, `${rarrow} ${payload.identifier}`]; + for (let i = 0; i < texts.length; i++) { + const span = document.createElement("span"); + span.innerText = texts[i]; + span.classList.add(`grid_col_${i + 1}`); + preview_object.payloads.append(span); + } + } + + const link_maker = file_ref => make_file_link(preview_object, file_ref); + + [...preview_object.copyright.childNodes].forEach(n => n.remove()); + populate_list(preview_object.copyright, + mapping.source_copyright.map(link_maker)); + + preview_object.dialog_context = dialog_context; + + return preview_object; +} +#EXPORT mapping_preview |