interlanguage-checker/src/main/js/Main.js

141 lines
5.1 KiB
JavaScript

import {$, doAfterLoad, footer, header, nav} from "@fwdekker/template";
import {html, render} from "htm/preact";
import Cookies from "js-cookie";
import {InterlangTable, MessageHandler, ValidatableInput} from "./DOM";
import {discoverNetwork, InterlangNetwork, MediaWiki, MediaWikiManager} from "./MediaWiki";
doAfterLoad(() => {
$("#nav").appendChild(nav());
$("#header").appendChild(header({
title: "Interlanguage Checker",
description: "Check the consistency of MediaWiki interlanguage links in a simple overview"
}));
$("#footer").appendChild(footer({
author: "Felix W. Dekker",
authorURL: "https://fwdekker.com/",
license: "MIT License",
licenseURL: "https://git.fwdekker.com/FWDekker/interlanguage-checker/src/branch/master/LICENSE",
vcs: "git",
vcsURL: "https://git.fwdekker.com/FWDekker/interlanguage-checker/",
version: "v%%VERSION_NUMBER%%"
}));
$("main").style.display = null;
});
doAfterLoad(async () => {
const urlInput = new ValidatableInput($("#url"), (value) => {
if (value.trim() === "")
return "API URL must not be empty.";
try {
new URL(value); // Throws exception if invalid
return "";
} catch (error) {
try {
new URL(`http://${value}`);
$("#url").value = `http://${value}`;
return "";
} catch {
return error.message;
}
}
});
const articleInput = new ValidatableInput($("#article"), (value) => {
return value.trim() === "" ? "Article must not be empty" : "";
});
const checkButton = $("#check");
const messageHandler = new MessageHandler($("#messages"))
.setCallback((level, message) => {
if (level === "error") console.error(message);
});
let previousUrl = undefined;
let mwm = undefined;
const submit = async () => {
Cookies.set("api-url", urlInput.getValue(), {expires: 10 * 365, secure: true, sameSite: "lax"});
// Clean up
urlInput.showBlank();
articleInput.showBlank();
messageHandler.clear();
const oldTable = $("#networkTable");
if (oldTable !== null)
oldTable.parentNode.removeChild(oldTable);
// Validate
const urlValidity = urlInput.validate();
if (urlValidity !== "") return messageHandler.handle("error", urlValidity);
const articleValidity = articleInput.validate();
if (articleValidity !== "") return messageHandler.handle("error", articleValidity);
// Initialize
if (urlInput.getValue() !== previousUrl) {
messageHandler.handle("progress", `Initializing <code>${urlInput.getValue()}</code>`);
try {
const mw = await new MediaWiki(urlInput.getValue()).init();
mwm = await new MediaWikiManager().init(mw);
} catch (error) {
messageHandler.handle("error", error);
return;
}
previousUrl = urlInput.getValue();
}
// Discover
discoverNetwork(mwm, articleInput.getValue(), it => messageHandler.handle("progress", it))
.then(it => new InterlangNetwork(it.pages, it.redirects))
.then(network => {
messageHandler.handle("progress", "Creating table");
const form = $("#networkTableForm");
form.textContent = "";
render(html`<${InterlangTable} id="networkTable" network=${network} />`, form);
switch (network.getVerdict()) {
case "perfect":
messageHandler.handle("complete", "A perfect network! 🙂");
break;
case "broken":
messageHandler.handle("warning", "The network is broken 😞<br />Hover over an icon for more information.");
break;
case "flawed":
messageHandler.handle("warning", "The network is complete but flawed 😕<br />Hover over an icon for more information.");
break;
}
})
.catch(error => messageHandler.handle("error", error));
};
urlInput.input.addEventListener("keypress", (event) => {
if (event.key.toLowerCase() === "enter") submit();
});
articleInput.input.addEventListener("keypress", (event) => {
if (event.key.toLowerCase() === "enter") submit();
});
checkButton.addEventListener("click", () => submit());
// Read inputs from cookies
if (Cookies.get("api-url") !== undefined) {
urlInput.setValue(Cookies.get("api-url"));
articleInput.input.focus();
}
// Read inputs from URL
const currentParams = new URLSearchParams(window.location.search);
if (currentParams.has("api")) {
urlInput.setValue(currentParams.get("api"));
articleInput.input.focus();
}
if (currentParams.has("article")) articleInput.setValue(currentParams.get("article"));
if (currentParams.has("api") && currentParams.has("article")) await submit();
});