termscp site

This commit is contained in:
veeso
2022-12-27 16:42:25 +01:00
parent 298d590306
commit 12fe10100b
26 changed files with 2157 additions and 0 deletions

35
site/js/core.js Normal file
View File

@@ -0,0 +1,35 @@
/**
* @description return navigator language. If language is not supported default will be returned
* @returns {string}
*/
function getNavigatorLanguage() {
let lang = navigator.language;
// Complete lang
if (languageSupported(lang)) {
return lang;
}
// Reduced lang
lang = lang.split(/[-_]/)[0] || "en";
if (!languageSupported(lang)) {
return "en";
}
return lang;
}
/**
* @description check whether provided language is supported by the website
* @param {string} lang
* @returns {boolean}
*/
function languageSupported(lang) {
return ["en", "zh-CN", "it", "fr", "es"].includes(lang);
}
/**
* @description update website language
* @param {string} lang
*/
function setSiteLanguage(lang) {
setLanguage(lang);
}

133
site/js/events.js Normal file
View File

@@ -0,0 +1,133 @@
const hashBlacklist = ["#menu"];
const converter = new showdown.Converter({ tables: true });
/**
* @description handle hash change
*/
function onHashChange() {
const hash = location.hash;
if (!hashBlacklist.includes(hash) && hash.length > 0) {
selectMenuEntry(location.hash);
loadPage(hash);
} else if (hash.length === 0 || hash === "#") {
loadPage("#intro");
}
}
/**
* @description select menu entry
* @param {*} hash
*/
function selectMenuEntry(hash) {
// Remove current entry
$(".pure-menu-selected").removeClass("pure-menu-selected");
$('a[href$="' + hash + '"]')
.parent()
.addClass("pure-menu-selected");
}
/**
* @description load page associated to hash
* @param {string} hash
*/
function loadPage(hash) {
switch (hash) {
case "#intro":
loadHtml("intro.html");
break;
case "#get-started":
loadHtml("get-started.html");
break;
case "#user-manual":
loadUserManual();
break;
case "#updates":
loadHtml("updates.html");
break;
case "#changelog":
loadMarkdown(
"https://raw.githubusercontent.com/veeso/termscp/main/CHANGELOG.md"
);
break;
}
window.scrollTo(0, 0);
}
function loadHtml(page) {
const url = "html/" + page;
$("#main").load(url, function () {
onPageLoaded();
});
}
function loadMarkdown(page) {
getMarkdown(page, function (md) {
const div = jQuery("<div/>", {
id: page,
class: "container markdown",
});
div.html(converter.makeHtml(md));
$("#main").empty();
$("#main").append(div);
onPageLoaded();
});
}
/**
* @description get markdown and pass result to onLoaded
* @param {string} url
* @param {function} onLoaded
*/
function getMarkdown(url, onLoaded) {
$.ajax({
url,
type: "GET",
dataType: "text",
success: onLoaded,
});
}
function onMenuBurgerClick() {
const active = $("#menu").hasClass("active");
if (active) {
$("#layout").removeClass("active");
$("#menu").removeClass("active");
} else {
$("#layout").addClass("active");
$("#menu").addClass("active");
}
}
function loadUserManual() {
// Load language
const lang = getNavigatorLanguage();
if (lang === "en") {
loadMarkdown(
`https://raw.githubusercontent.com/veeso/termscp/main/docs/man.md`
);
} else {
loadMarkdown(
`https://raw.githubusercontent.com/veeso/termscp/main/docs/${lang}/man.md`
);
}
}
function onPageLoaded() {
reloadTranslations();
}
// Register
window.onhashchange = onHashChange;
// Startup
$(function () {
onHashChange();
// Init language
setSiteLanguage(getNavigatorLanguage());
// Burger event listener
$("#menu-burger").on("click", onMenuBurgerClick);
$(".pure-menu-heading").on("click", function () {
location.hash = "#";
onHashChange();
});
});

1
site/js/lang.min.js vendored Normal file
View File

@@ -0,0 +1 @@
var currentLanguage=null;var languagePath="lang/";var currentLanguageDict=null;function setLanguage(lang){currentLanguage=lang;const jsonFile=languagePath+currentLanguage+".json";$.getJSON(jsonFile,function(langData){currentLanguageDict=flatDict(langData);reloadTranslations()})}function reloadTranslations(){$("[translate]").each(function(){const translationAttr=$(this).attr("translate");$(this).text(getInstantTranslation(translationAttr))})}function getInstantTranslation(key){if(currentLanguageDict!==null&&key in currentLanguageDict){return currentLanguageDict[key]}else{return"{{ "+key+" }}"}}function flatDict(dict){const iterNode=(flatten,path,node)=>{for(const key of Object.keys(node)){const child=node[key];const childKey=path?path+"."+key:key;if(typeof child==="object"){flatten=iterNode(flatten,childKey,child)}else{flatten[childKey]=child}}return flatten};return iterNode({},null,dict)}

32
site/js/resolvers.js Normal file
View File

@@ -0,0 +1,32 @@
/**
* @description resolve copyright year
*/
function resolveCopyright() {
const year = new Date().getFullYear();
$("[resolve-copyright]").each(function () {
$(this).text(year);
});
}
/**
* @description resolve video fallback source in case fails. Uses an image instead
*/
function resolveVideoFallback() {
$("[resolve-video-fallback]").each(function () {
const fallback = $(this).attr("resolve-video-fallback");
// Add listener
$(this).on("error", function () {
const image = document.createElement("img");
image.src = fallback;
image.classList = ["preview"];
$(this).parent().replaceWith(image);
});
});
}
// init
$(function () {
resolveCopyright();
resolveVideoFallback();
});