feat: doom runs inline as .doom/doom.sh instead of a floating draggable window

cds into a fake .doom folder (breadcrumb + file listing match every other page); .. is a real link back to wherever you typed doom from, so leaving is just normal pjax navigation.
This commit is contained in:
kgva CMS
2026-08-10 22:54:15 +00:00
parent d3f63251eb
commit 3c7cc6ae6b
2 changed files with 43 additions and 80 deletions
+8 -39
View File
@@ -276,48 +276,17 @@ body:not(.home) .menu { display: none; }
}
.proj-path__seg--last { font-weight: 700; }
/* secret `doom` — a small window floating over the site, sized to the 4:3 game */
.doom-window {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: min(92vw, 640px);
z-index: 9999;
display: flex;
flex-direction: column;
background: #000;
border: 1px solid var(--color-text-primary);
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.45);
}
.doom-window__bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.25rem 0.25rem 0.25rem 0.6rem;
font-family: var(--font-family-mono);
font-size: var(--font-size-small);
color: #fff;
background: #000;
cursor: move;
user-select: none;
}
.doom-window__close {
cursor: pointer;
color: #fff;
background: none;
border: none;
font: inherit;
line-height: 1;
padding: 0 0.6ch;
}
.doom-window__close:hover { color: #000; background: #fff; }
.doom-window iframe {
/* secret `doom` — runs inline as doom.sh inside a fake .doom folder, same
file-listing chrome as any other page. sized to the classic 4:3 game. */
.doom-player {
width: 100%;
aspect-ratio: 4 / 3;
height: auto;
border: 0;
background: #000;
}
.doom-player iframe {
width: 100%;
height: 100%;
border: 0;
display: block;
}
+35 -41
View File
@@ -203,50 +203,44 @@
setTimeout(function () { pre.remove(); }, 4200);
}
// secret: `doom` boots shareware DOOM (id Software) in a draggable window
// secret: `doom` cds into a fake ".doom" folder and runs doom.sh — shareware
// DOOM (id Software), embedded inline in the same file-listing chrome as any
// other page (not a floating window). ".." is a real link back to wherever
// you typed the command from, so leaving is just normal navigation — nav.js's
// pjax swap restores the real page (and real breadcrumb) on its own.
function doom() {
if (document.querySelector(".doom-window")) return;
var win = document.createElement("div");
win.className = "doom-window";
var bar = document.createElement("div");
bar.className = "doom-window__bar";
var label = document.createElement("span");
label.className = "doom-window__title";
label.textContent = "doom";
var close = document.createElement("button");
close.className = "doom-window__close";
close.setAttribute("aria-label", "close");
close.textContent = "✕";
var frame = document.createElement("iframe");
frame.src = "https://archive.org/embed/DoomsharewareEpisode";
frame.setAttribute("allowfullscreen", "");
frame.allow = "fullscreen; autoplay; gamepad";
bar.appendChild(label);
bar.appendChild(close);
win.appendChild(bar);
win.appendChild(frame);
document.body.appendChild(win);
var main = document.getElementById("main-content");
if (!main || document.querySelector(".doom-embed")) return;
var back = window.location.pathname + window.location.search;
function kill() { win.remove(); document.removeEventListener("keydown", esc); }
function esc(e) { if (e.key === "Escape") kill(); }
close.addEventListener("click", kill);
document.addEventListener("keydown", esc);
var pathEl = document.querySelector(".prompt__path");
if (pathEl && /\$$/.test(pathEl.innerHTML)) {
pathEl.innerHTML = pathEl.innerHTML.replace(/\$$/, '/<span class="prompt__seg">.doom</span>$');
}
// drag by the title bar (shield the iframe so it doesn't swallow the mouse)
bar.addEventListener("mousedown", function (e) {
if (e.target === close) return;
var r = win.getBoundingClientRect();
win.style.left = r.left + "px";
win.style.top = r.top + "px";
win.style.transform = "none";
var dx = e.clientX - r.left, dy = e.clientY - r.top;
frame.style.pointerEvents = "none";
function mv(ev) { win.style.left = (ev.clientX - dx) + "px"; win.style.top = (ev.clientY - dy) + "px"; }
function up() { frame.style.pointerEvents = ""; document.removeEventListener("mousemove", mv); document.removeEventListener("mouseup", up); }
document.addEventListener("mousemove", mv);
document.addEventListener("mouseup", up);
e.preventDefault();
});
main.innerHTML =
'<div class="tui tui--files filebrowser doom-embed">' +
'<p class="tui__cmd"><span class="tui__sym">$</span> ls</p>' +
'<p class="tui__cmd tui__total">total 1</p>' +
'<ul class="tui__ls">' +
'<li><a href="' + back + '" data-name="..">' +
'<span class="tui__perm">drwxr-xr-x</span><span class="tui__name">..</span>' +
'</a></li>' +
'<li><a data-name="doom.sh" class="is-selected">' +
'<span class="tui__perm">-rwxr-xr-x</span><span class="tui__name">doom.sh</span>' +
'</a></li>' +
'</ul>' +
'<figure class="tui__preview">' +
'<div class="doom-player">' +
'<iframe src="https://archive.org/embed/DoomsharewareEpisode" allowfullscreen allow="fullscreen; autoplay; gamepad"></iframe>' +
'</div>' +
'<figcaption class="tui__status">doom.sh — running</figcaption>' +
'</figure>' +
'</div>';
// re-run the same wiring a real pjax navigation would (file-row hover/
// click, route rebuilding) against this injected markup
document.dispatchEvent(new CustomEvent("pjax:load"));
}
function egg(lc, raw) {