unbounded
This commit is contained in:
parent
4bcc2e5e1c
commit
2433d91271
3 changed files with 59 additions and 43 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "the-fold-within",
|
"name": "the-fold-within",
|
||||||
"version": "3.0.0",
|
"version": "3.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pdf-parse": "^1.1.1"
|
"pdf-parse": "^1.1.1"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,9 +167,8 @@ function renderSubNav(parent) {
|
||||||
async function handleHash() {
|
async function handleHash() {
|
||||||
els.viewer.innerHTML = "";
|
els.viewer.innerHTML = "";
|
||||||
const rel = location.hash.replace(/^#\//, "");
|
const rel = location.hash.replace(/^#\//, "");
|
||||||
const parts = rel.split("/").filter(Boolean); // e.g., ["about", "Mark"]
|
const parts = rel.split("/").filter(Boolean);
|
||||||
|
|
||||||
// Determine current depth parent for subnav
|
|
||||||
const currentParentPath = parts.slice(0, -1).join("/") || parts[0] || null;
|
const currentParentPath = parts.slice(0, -1).join("/") || parts[0] || null;
|
||||||
|
|
||||||
if (currentParentPath !== currentParent) {
|
if (currentParentPath !== currentParent) {
|
||||||
|
|
@ -177,7 +176,6 @@ async function handleHash() {
|
||||||
renderSubNav(currentParent);
|
renderSubNav(currentParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync sidebar section to top-level
|
|
||||||
const topSection = parts[0] || null;
|
const topSection = parts[0] || null;
|
||||||
if (topSection && indexData.sections.includes(topSection)) {
|
if (topSection && indexData.sections.includes(topSection)) {
|
||||||
els.sectionSelect.value = topSection;
|
els.sectionSelect.value = topSection;
|
||||||
|
|
@ -186,7 +184,6 @@ async function handleHash() {
|
||||||
|
|
||||||
if (!rel) return renderDefault();
|
if (!rel) return renderDefault();
|
||||||
|
|
||||||
// CASE: Trailing slash → render index at *current* level
|
|
||||||
if (rel.endsWith('/')) {
|
if (rel.endsWith('/')) {
|
||||||
const currentPath = parts.join("/");
|
const currentPath = parts.join("/");
|
||||||
|
|
||||||
|
|
@ -202,34 +199,12 @@ async function handleHash() {
|
||||||
const html = marked.parse(src || `# ${currentPath.split("/").pop()}\n\nNo content yet.`);
|
const html = marked.parse(src || `# ${currentPath.split("/").pop()}\n\nNo content yet.`);
|
||||||
els.viewer.innerHTML = `<article class="markdown">${html}</article>`;
|
els.viewer.innerHTML = `<article class="markdown">${html}</article>`;
|
||||||
} else {
|
} else {
|
||||||
const iframe = document.createElement("iframe");
|
renderIframe("/" + indexFile.path);
|
||||||
iframe.src = "/" + indexFile.path;
|
|
||||||
iframe.loading = "eager";
|
|
||||||
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
|
|
||||||
els.viewer.appendChild(iframe);
|
|
||||||
|
|
||||||
iframe.onload = () => {
|
|
||||||
try {
|
|
||||||
const doc = iframe.contentDocument;
|
|
||||||
const body = doc.body;
|
|
||||||
const hasContent = body && body.innerText.trim().length > 50;
|
|
||||||
if (!hasContent) {
|
|
||||||
doc.body.innerHTML = `
|
|
||||||
<div style="text-align:center;padding:4rem;font-family:Inter,sans-serif;">
|
|
||||||
<h1 style="color:#e6e3d7;">${currentPath.split("/").pop()}</h1>
|
|
||||||
<p style="color:#888;">No content yet.</p>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
doc.body.style.background = "#0b0b0b";
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
els.viewer.innerHTML = `<h1>${currentPath.split("/").pop()}</h1><p>No content yet.</p>`;
|
els.viewer.innerHTML = `<h1>${currentPath.split("/").pop()}</h1><p>No content yet.</p>`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No index → show children or fallback
|
|
||||||
if (topSection) {
|
if (topSection) {
|
||||||
els.sectionSelect.value = topSection;
|
els.sectionSelect.value = topSection;
|
||||||
renderList();
|
renderList();
|
||||||
|
|
@ -239,14 +214,13 @@ async function handleHash() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// CASE: Direct file
|
|
||||||
else {
|
else {
|
||||||
const file = indexData.flat.find(f => f.path === rel);
|
const file = indexData.flat.find(f => f.path === rel);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
els.viewer.innerHTML = "<h1>404</h1><p>Not found.</p>";
|
els.viewer.innerHTML = "<h1>404</h1><p>Not found.</p>";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe(file.path);
|
file.ext === ".md" ? await renderMarkdown(file.path) : renderIframe("/" + file.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -255,11 +229,17 @@ async function renderMarkdown(rel) {
|
||||||
els.viewer.innerHTML = `<article class="markdown">${marked.parse(src || "# Untitled")}</article>`;
|
els.viewer.innerHTML = `<article class="markdown">${marked.parse(src || "# Untitled")}</article>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderIframe(rel) {
|
function renderIframe(src) {
|
||||||
const iframe = document.createElement("iframe");
|
const iframe = document.createElement("iframe");
|
||||||
iframe.src = "/" + rel;
|
iframe.src = src;
|
||||||
iframe.loading = "eager";
|
iframe.loading = "eager";
|
||||||
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms");
|
iframe.setAttribute("sandbox", "allow-same-origin allow-scripts allow-forms allow-popups");
|
||||||
|
iframe.style.width = "100vw";
|
||||||
|
iframe.style.height = "calc(100vh - var(--topbar-h) - var(--subnav-h))";
|
||||||
|
iframe.style.border = "none";
|
||||||
|
iframe.style.borderRadius = "0";
|
||||||
|
iframe.style.margin = "0";
|
||||||
|
|
||||||
els.viewer.appendChild(iframe);
|
els.viewer.appendChild(iframe);
|
||||||
|
|
||||||
iframe.onload = () => {
|
iframe.onload = () => {
|
||||||
|
|
@ -267,11 +247,29 @@ function renderIframe(rel) {
|
||||||
const doc = iframe.contentDocument;
|
const doc = iframe.contentDocument;
|
||||||
const style = doc.createElement("style");
|
const style = doc.createElement("style");
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
html,body{background:#0b0b0b;color:#e6e3d7;font-family:Inter,sans-serif;margin:0;padding:2rem;}
|
html, body {
|
||||||
*{max-width:720px;margin:auto;}
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
margin: 0;
|
||||||
|
padding: 3rem 4vw;
|
||||||
|
}
|
||||||
|
* { max-width: 100%; }
|
||||||
img, video, iframe { max-width: 100%; height: auto; }
|
img, video, iframe { max-width: 100%; height: auto; }
|
||||||
`;
|
`;
|
||||||
doc.head.appendChild(style);
|
doc.head.appendChild(style);
|
||||||
|
|
||||||
|
const body = doc.body;
|
||||||
|
const hasContent = body && body.innerText.trim().length > 50;
|
||||||
|
if (!hasContent) {
|
||||||
|
doc.body.innerHTML = `
|
||||||
|
<div style="text-align:center;padding:6rem;font-family:Inter,sans-serif;">
|
||||||
|
<h1 style="color:#e6e3d7;">${src.split("/").pop().replace(/\..*$/, "")}</h1>
|
||||||
|
<p style="color:#888;">No content yet.</p>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
doc.body.style.background = "transparent";
|
||||||
|
}
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ body.sidebar-open #sidebar { transform: translateX(0); }
|
||||||
margin-top: calc(var(--topbar-h) + var(--subnav-h)); margin-left: 0;
|
margin-top: calc(var(--topbar-h) + var(--subnav-h)); margin-left: 0;
|
||||||
transition: margin-left var(--transition), margin-top var(--transition);
|
transition: margin-left var(--transition), margin-top var(--transition);
|
||||||
min-height: calc(100vh - var(--topbar-h) - var(--subnav-h));
|
min-height: calc(100vh - var(--topbar-h) - var(--subnav-h));
|
||||||
padding: 2rem 1rem;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 1024px) {
|
@media (min-width: 1024px) {
|
||||||
|
|
@ -180,8 +180,22 @@ body.sidebar-open #sidebar { transform: translateX(0); }
|
||||||
.content { margin-left: 300px; }
|
.content { margin-left: 300px; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BREATHING HORIZON: Full-Field Viewer */
|
||||||
|
.viewer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
transition: background 1s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewer:hover {
|
||||||
|
background: radial-gradient(circle at center, #111 0%, #0b0b0b 80%);
|
||||||
|
}
|
||||||
|
|
||||||
.viewer > * {
|
.viewer > * {
|
||||||
max-width: 720px; margin: auto; padding: 2rem 1rem;
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 3rem 4vw;
|
||||||
animation: fadeIn .4s ease-out;
|
animation: fadeIn .4s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,7 +205,11 @@ body.sidebar-open #sidebar { transform: translateX(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.viewer iframe {
|
.viewer iframe {
|
||||||
width: 100%; height: calc(100vh - var(--topbar-h) - var(--subnav-h) - 80px);
|
flex: 1;
|
||||||
border: 0; border-radius: var(--radius); background: transparent;
|
width: 100vw;
|
||||||
|
min-height: 100vh;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
margin: 0;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue