Files
the-monospace-web-pandoc/index.js
2024-08-27 07:35:43 +02:00

98 lines
2.8 KiB
JavaScript

function firstEvent(element, name) {
return new Promise(resolve => {
element.addEventListener(name, resolve);
});
}
function gridCellDimensions() {
const element = document.createElement("div");
element.style.position = "fixed";
element.style.height = "var(--line-height)";
element.style.width = "1ch";
document.body.appendChild(element);
const rect = element.getBoundingClientRect();
document.body.removeChild(element);
return { width: rect.width, height: rect.height };
}
const defaultRatio = 16/9;
// Set the ratio variable on each media.
function setRatios() {
const medias = document.querySelectorAll("img, video");
for (media of medias) {
function onLoaded() {
var ratio = defaultRatio;
switch (media.tagName) {
case "IMG":
ratio = media.naturalWidth / media.naturalHeight;
break;
case "VIDEO":
ratio = media.videoWidth / media.videoHeight;
break;
}
if (ratio != NaN) {
console.log("Setting ratio", ratio, "for element", media);
media.style.setProperty("--ratio", ratio);
}
}
switch (media.tagName) {
case "IMG":
if (!media.loaded) {
media.style.setProperty("--ratio", defaultRatio); // default while loading
firstEvent(media, "load").then(onLoaded);
console.log("Image loaded", media);
}
break;
case "VIDEO":
if (media.readyState != 4) {
media.style.setProperty("--ratio", defaultRatio); // default while loading
firstEvent(media, "loadeddata").then(onLoaded);
console.log("Video ready", media);
}
break;
}
onLoaded();
}
}
setRatios();
function checkOffsets() {
const ignoredTagNames = new Set([
"THEAD",
"TBODY",
"TFOOT",
"TR",
"TD",
"TH",
]);
const cell = gridCellDimensions();
const elements = document.querySelectorAll("body :not(.debug-grid, .debug-toggle)");
for (const element of elements) {
if (ignoredTagNames.has(element.tagName)) {
continue;
}
const rect = element.getBoundingClientRect();
if (rect.width === 0 && rect.height === 0) {
continue;
}
const top = rect.top + window.scrollY;
const left = rect.left + window.scrollX;
const offset = top % (cell.height / 2);
if(offset > 0) {
element.classList.add("off-grid");
console.error("Incorrect vertical offset for", element, "with remainder", top % cell.height, "when expecting divisible by", cell.height / 2);
} else {
element.classList.remove("off-grid");
}
}
}
const debugToggle = document.querySelector(".debug-toggle");
function onDebugToggle() {
document.body.classList.toggle("debug", debugToggle.checked);
}
debugToggle.addEventListener("change", onDebugToggle);
onDebugToggle();