SchOS/docs/Website/app.js
Nexoniarz 26bca020b6 licence: SchOS is GPL-2.0-or-later, no longer Apache-2.0
Nexoniarz is the sole author and SchOS was never published under
Apache-2.0, so this is a straight relicence. LICENSE is the FSF GPLv2 text,
every first-party SPDX header moves to GPL-2.0-or-later, and NOTICE,
README.md, docs/licensing.md and the site say so. projects/schfs-linux
follows the rest of the tree.

The GPL gives copyleft: a fork has to ship its source. It also lifts the
old "Linux drivers, never" rule, since GPL-2.0-only code combines with
GPL-2.0-or-later. "Or later" leaves room for GPLv3, but one binary still
has to pick one version, so docs/licensing.md now keeps Apache-2.0 and
GPLv3 code out of the kernel to keep Linux code possible there. BSD
4-clause code goes from "avoid" to "no", because the advertising clause
is GPL-incompatible.

LDLS still ships no .ko. That boundary is now project policy rather than
a legal requirement, and ldls.md, devices.md and licensing.md section 6
say so. refmod declares license=GPL, and ldls-check passes (27 checks).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 08:48:45 +02:00

115 lines
4.4 KiB
JavaScript

/* SPDX-License-Identifier: GPL-2.0-or-later
*
* Three behaviours, no framework:
* 1. the hero console types a real boot log
* 2. sections fade in once, as they arrive
* 3. the bar takes a shadow once the page has scrolled under it
*
* All three are decoration. If this file fails to load the page is still
* complete and still readable, which is the test any script on a
* documentation site should have to pass.
*
* Niveus does the rest: its own niveus.js wires the appearance buttons, and
* everything visual comes from the stylesheet. Nothing here sets a style.
*/
(function () {
"use strict";
var reduced = window.matchMedia &&
window.matchMedia("(prefers-reduced-motion: reduce)").matches;
/* ---- 1. the boot log ------------------------------------------------
* These are real lines from a real boot, not invented ones. The timer
* calibration line in particular is there because of what it cost: the
* clock ran seven times slow until a graphics driver was made to
* acknowledge its own interrupt. See docs/history/kernel.md.
*/
var LINES = [
{ t: "[ 0.000]", k: "SchIFT", s: " 64-bit, 2 cpus" },
{ t: "[ 0.004]", k: "cpu0", s: ": lapic timer 999941980 Hz, tsc 3792 MHz" },
{ t: "[ 0.049]", k: "virtio-gpu", s: ": 1280x800, 4000 KB framebuffer" },
{ t: "[ 0.088]", k: "e1000", s: ": 52:54:00:12:34:56, link up, irq 11" },
{ t: "[ 0.143]", k: "schfs", s: ": mounted 'schos', generation 2" },
{ t: "[ 0.169]", k: "net", s: ": eth0 10.0.2.15/255.255.255.0" },
{ t: "[ 0.204]", k: "schinit", s: ": ready (pid 1)" },
{ t: "[ 0.212]", k: "schinitd", s: ": 2 job(s) loaded, generation 1", g: true },
{ t: "", k: "", s: "# " }
];
var out = document.getElementById("bootlog");
/* The classes are Niveus text roles, so the log is coloured by the same
tokens as the rest of the page and follows the appearance with it. */
function span(cls, text) {
var e = document.createElement("span");
if (cls) e.className = cls;
e.textContent = text;
return e;
}
function emit(line) {
if (line.t) {
out.appendChild(span("nv-text-tertiary", line.t + " "));
out.appendChild(span("nv-text-accent", line.k));
}
out.appendChild(span(line.g ? "nv-text-success" : "", line.s));
out.appendChild(document.createTextNode("\n"));
}
if (out && reduced) {
LINES.forEach(emit); // the whole log at once, no animation
} else if (out) {
var i = 0;
(function step() {
if (i >= LINES.length) return;
emit(LINES[i++]);
/* Uneven on purpose: a boot that ticks out at a metronome's pace reads
as a progress bar rather than as a machine doing different work. */
setTimeout(step, 180 + Math.random() * 220);
})();
}
/* ---- 2. reveal on scroll ------------------------------------------ */
var targets = document.querySelectorAll("[data-reveal]");
if (reduced || !("IntersectionObserver" in window)) {
Array.prototype.forEach.call(targets, function (el) {
el.classList.add("is-revealed");
});
} else {
var io = new IntersectionObserver(function (entries) {
entries.forEach(function (entry) {
if (!entry.isIntersecting) return;
entry.target.classList.add("is-revealed");
io.unobserve(entry.target); // once, not on every scroll past
});
}, { rootMargin: "0px 0px -12% 0px", threshold: 0.05 });
Array.prototype.forEach.call(targets, function (el) { io.observe(el); });
}
/* ---- 3. the bar, once something has passed under it ---------------- */
var bar = document.querySelector(".nv-nav");
if (bar) {
var onScroll = function () {
if (window.scrollY > 8) bar.setAttribute("data-scrolled", "");
else bar.removeAttribute("data-scrolled");
};
addEventListener("scroll", onScroll, { passive: true });
onScroll();
}
/* ---- and remember the appearance ----------------------------------- */
/*
* Niveus changes the appearance; which one was chosen is this site's to
* keep. The inline script in <head> reads it back before first paint.
*/
document.documentElement.addEventListener("nv:theme", function (event) {
try {
localStorage.setItem("schos-theme", (event.detail && event.detail.theme) || "system");
} catch (e) { /* storage unavailable — the choice lasts this visit */ }
});
})();