aboutsummaryrefslogtreecommitdiff
/**
 * 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 common/browser.js IMPORT browser
#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);
    }
}

const file_preview_link = browser.runtime.getURL("html/file_preview.html");

/*
 * The default function to use to create file preview link. Links it creates can
 * be used to view files from IndexedDB.
 */
function make_file_link(preview_object, file_ref) {
    const a = document.createElement("a");
    a.href = `${file_preview_link}#${file_ref.sha256}`;
    a.innerText = file_ref.file;
    a.target = "_blank";
    return a;
}

function resource_preview(resource, preview_object, link_cb=make_file_link) {
    if (preview_object === undefined)
	preview_object = clone_template("resource_preview");

    preview_object.conforms_to.innerHTML = "";
    const schema_link     = document.createElement("a");
    schema_link.href      = resource.$schema;
    schema_link.innerText = resource.$schema;
    preview_object.conforms_to.append(schema_link);

    preview_object.identifier.innerText  = resource.identifier;
    preview_object.long_name.innerText   = resource.long_name;
    preview_object.uuid.innerText        = resource.uuid || "not set";
    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());

    const deps_refs = resource.dependencies || [];
    populate_list(preview_object.dependencies,
		  deps_refs.map(res_ref => res_ref.identifier));

    const link_maker = file_ref => link_cb(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));

    return preview_object;
}
#EXPORT resource_preview

function mapping_preview(mapping, preview_object, link_cb=make_file_link) {
    if (preview_object === undefined)
	preview_object = clone_template("mapping_preview");

    preview_object.conforms_to.innerHTML = "";
    const schema_link     = document.createElement("a");
    schema_link.href      = mapping.$schema;
    schema_link.innerText = mapping.$schema;
    preview_object.conforms_to.append(schema_link);

    preview_object.identifier.innerText  = mapping.identifier;
    preview_object.long_name.innerText   = mapping.long_name;
    preview_object.uuid.innerText        = mapping.uuid || "not set";
    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());
    const payload_entries = Object.entries(mapping.payloads || {}).sort();
    for (const [pattern, payload] of payload_entries) {
	/* 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}`];
	const payload_entry = clone_template("pattern_payload_entry");
	payload_entry.pattern.innerText = pattern;
	payload_entry.payload.innerText = payload.identifier;
	preview_object.payloads.append(payload_entry.main_div);
    }

    const link_maker = file_ref => link_cb(preview_object, file_ref);

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

    return preview_object;
}
#EXPORT mapping_preview