Files
com.xaymar.www/assets/js/highlight.mjs
T
Michael Fabian 'Xaymar' Dirks 143b9b685d Only load languages that are actually used
Firefox doesn't like 429 Too Many Requests at all
2024-06-05 06:45:22 +02:00

96 lines
2.6 KiB
JavaScript

'use strict';
// Highlight.JS: https://highlightjs.org/
async function initializeHighlightJS() {
const languageRE = /\blanguage-([a-zA-Z0-9_\-]+)\b/gi;
const noLanguageRE = /\bno-language\b/gi;
const languages = new Set();
const selector = "code.block[class*=\"language\"]";
const blocks = document.querySelectorAll(selector);
// Early-Exit if there's nothing to highlight anyway to reduce waste.
if (blocks.length == 0) {
console.log("highlight.JS: Skipping, as it is not needed here.");
return;
}
// Load and configure highlight.JS
console.log("highlight.JS: Loading...");
let highlightJS = await import("./highlightjs/highlight.mjs");
window.highlightJS = highlightJS.default;
console.log("highlight.JS: Configuring...");
window.highlightJS.configure({
"noHighlightRe": noLanguageRE,
"languageDetectRe": languageRE,
"cssSelector": "code.block[class*=\"language\"]",
"throwUnescapedHTML": true,
});
// Find all languages used.
for (let block of blocks) {
for (let classname of block.classList) {
for (let match of classname.matchAll(languageRE)) {
if (match.length > 0) {
languages.add(match[1]);
}
}
}
}
// Import all languages.
let langs = [];
for (let lang of languages) {
console.log(`highlight.JS: Importing language definition for '${lang}'...`);
langs.push(new Promise(async (resolve, reject) => {
const start = performance.now();
const max_attempts = 5;
let attempt = 0;
let mod = undefined;
let err = null;
for (let attempt = 1; attempt <= 5; attempt++) {
try {
// Firefox breaks here because it hates 429 Too Many Requests. All other browsers work.
mod = await import(`./highlightjs/languages/${lang}.min.js`);
break;
} catch (ex) {
err = ex;
await new Promise((resolve, reject) => {
setTimeout(() => { resolve() }, 1000);
})
}
}
if (!mod) {
reject(err);
} else {
window.highlightJS.registerLanguage(lang, mod.default);
console.log(`highlight.JS: Imported language definition for '${lang}' after ${(performance.now() - start).toFixed(2)}ms.`);
resolve(mod);
}
}));
}
await Promise.allSettled(langs)
// Highlight everything.
function highlightAllCode() {
console.log(`highlight.JS: Applying highlighting all valid code blocks...`);
try {
window.highlightJS.highlightAll();
} catch (ex) {
console.error(`highlight.JS: ${ex}`);
}
};
if (document.readyState === "complete"
|| document.readyState === "loaded"
|| document.readyState === "interactive") {
highlightAllCode();
} else {
document.addEventListener('DOMContentLoaded', () => {
highlightAllCode();
});
}
}
initializeHighlightJS();