Refactor: Remove obsolete JavaScript managers and utilities
- Deleted NavigationManager, RecentPlotsManager, SearchManager, SortManager, StatsManager, ThemeManager, Utils, and ViewManager classes. - Updated gallery builder to improve asset copying logic with a more efficient modification time check. - Cleaned up gallery HTML template by removing subdirectory listing and embedding gallery data as JSON. - Added CLAUDE.md for project documentation and guidelines.
This commit is contained in:
@@ -2,16 +2,9 @@
|
||||
FOLDER TREE
|
||||
======================================== */
|
||||
.folder-tree {
|
||||
background: var(--tree-bg);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
font-family: 'JetBrains Mono', 'Fira Code', 'Courier New', monospace;
|
||||
font-size: 0.85rem;
|
||||
max-height: 350px;
|
||||
overflow-y: auto;
|
||||
transition: all 0.3s ease;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
|
||||
@@ -9,20 +9,20 @@ export class NavigationManager {
|
||||
const currentPath = window.location.pathname;
|
||||
const pathParts = currentPath.split('/').filter(part => part !== '' && part !== 'index.html');
|
||||
const breadcrumb = document.getElementById('breadcrumb');
|
||||
|
||||
|
||||
if (!breadcrumb) return;
|
||||
|
||||
|
||||
if (pathParts.length === 0) {
|
||||
breadcrumb.innerHTML = '<span>🏠 Root</span>';
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let html = '<a href="/">🏠 Root</a>';
|
||||
|
||||
|
||||
for (let i = 0; i < pathParts.length; i++) {
|
||||
const part = pathParts[i];
|
||||
html += '<span class="separator">/</span>';
|
||||
|
||||
|
||||
if (i === pathParts.length - 1) {
|
||||
html += `<span>${decodeURIComponent(part)}</span>`;
|
||||
} else {
|
||||
@@ -31,19 +31,35 @@ export class NavigationManager {
|
||||
html += `<a href="${relativePath}">${decodeURIComponent(part)}</a>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
breadcrumb.innerHTML = html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract subdirs and item count from a parsed page document.
|
||||
* Reads from the embedded #gallery-data JSON element.
|
||||
*/
|
||||
extractPageData(doc) {
|
||||
const dataEl = doc.getElementById('gallery-data');
|
||||
if (dataEl) {
|
||||
try {
|
||||
const data = JSON.parse(dataEl.textContent);
|
||||
return { subdirs: data.subdirs || [], itemCount: data.item_count || 0 };
|
||||
} catch {}
|
||||
}
|
||||
// Fallback for pages that pre-date the data element
|
||||
return { subdirs: [], itemCount: doc.querySelectorAll('.grid-item').length };
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and display the folder tree structure
|
||||
*/
|
||||
async buildFolderTree() {
|
||||
const treeContainer = document.getElementById('folderTree');
|
||||
const currentPath = window.location.pathname;
|
||||
|
||||
|
||||
if (!treeContainer) return;
|
||||
|
||||
|
||||
try {
|
||||
const tree = await this.buildTreeRecursive(currentPath, 0, currentPath);
|
||||
treeContainer.innerHTML = tree;
|
||||
@@ -61,52 +77,41 @@ export class NavigationManager {
|
||||
const indent = ' '.repeat(depth);
|
||||
return `<div class="tree-item">${indent}└─ ...</div>`;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
const response = await fetch(path);
|
||||
const htmlContent = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlContent, 'text/html');
|
||||
|
||||
const subdirs = doc.querySelectorAll('h2 + ul li a');
|
||||
const items = doc.querySelectorAll('.grid-item');
|
||||
|
||||
|
||||
const { subdirs, itemCount } = this.extractPageData(doc);
|
||||
const baseUrl = path.replace(/\/[^\/]*$/, '/');
|
||||
|
||||
// Check if this is an empty directory (only one subdirectory, no items)
|
||||
if (items.length === 0 && subdirs.length === 1) {
|
||||
const subdir = subdirs[0];
|
||||
const href = subdir.getAttribute('href');
|
||||
if (href) {
|
||||
const baseUrl = path.replace(/\/[^\/]*$/, '/');
|
||||
const subPath = baseUrl + href;
|
||||
|
||||
const collapsedPath = await this.getCollapsedPath(path, subPath);
|
||||
return await this.buildCollapsedTreeItem(collapsedPath, depth, currentPath, maxDepth);
|
||||
}
|
||||
if (itemCount === 0 && subdirs.length === 1) {
|
||||
const subPath = baseUrl + subdirs[0] + '/index.html';
|
||||
const collapsedPath = await this.getCollapsedPath(path, subPath);
|
||||
return await this.buildCollapsedTreeItem(collapsedPath, depth, currentPath, maxDepth);
|
||||
}
|
||||
|
||||
|
||||
// Normal directory processing
|
||||
const indent = ' '.repeat(depth);
|
||||
const folderName = path.split('/').filter(p => p !== '' && p !== 'index.html').pop() || 'Gallery';
|
||||
const totalItems = items.length + subdirs.length;
|
||||
const totalItems = itemCount + subdirs.length;
|
||||
const arrow = depth === 0 ? '' : '└─ ';
|
||||
|
||||
|
||||
let html = '';
|
||||
if (path === currentPath) {
|
||||
html += `<div class="tree-item">${indent}${arrow}📁 <span class="tree-current">${folderName}</span> (${totalItems} items)</div>`;
|
||||
} else {
|
||||
html += `<div class="tree-item">${indent}${arrow}📁 <a href="${path}" class="tree-link">${folderName}</a> (${totalItems} items)</div>`;
|
||||
}
|
||||
|
||||
for (let i = 0; i < subdirs.length; i++) {
|
||||
const subdir = subdirs[i];
|
||||
const href = subdir.getAttribute('href');
|
||||
if (href) {
|
||||
const baseUrl = path.replace(/\/[^\/]*$/, '/');
|
||||
const subPath = baseUrl + href;
|
||||
html += await this.buildTreeRecursive(subPath, depth + 1, currentPath, maxDepth);
|
||||
}
|
||||
|
||||
for (const subdir of subdirs) {
|
||||
const subPath = baseUrl + subdir + '/index.html';
|
||||
html += await this.buildTreeRecursive(subPath, depth + 1, currentPath, maxDepth);
|
||||
}
|
||||
|
||||
|
||||
return html;
|
||||
} catch (error) {
|
||||
const indent = ' '.repeat(depth);
|
||||
@@ -122,41 +127,30 @@ export class NavigationManager {
|
||||
async getCollapsedPath(startPath, currentPath) {
|
||||
const pathSegments = [];
|
||||
let path = startPath;
|
||||
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
const response = await fetch(path);
|
||||
const htmlContent = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlContent, 'text/html');
|
||||
|
||||
const subdirs = doc.querySelectorAll('h2 + ul li a');
|
||||
const items = doc.querySelectorAll('.grid-item');
|
||||
|
||||
|
||||
const { subdirs, itemCount } = this.extractPageData(doc);
|
||||
const folderName = path.split('/').filter(p => p !== '' && p !== 'index.html').pop() || 'Gallery';
|
||||
pathSegments.push({ name: folderName, path: path });
|
||||
|
||||
if (items.length > 0 || subdirs.length !== 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
const subdir = subdirs[0];
|
||||
const href = subdir.getAttribute('href');
|
||||
if (href) {
|
||||
const baseUrl = path.replace(/\/[^\/]*$/, '/');
|
||||
path = baseUrl + href;
|
||||
} else {
|
||||
|
||||
if (itemCount > 0 || subdirs.length !== 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
const baseUrl = path.replace(/\/[^\/]*$/, '/');
|
||||
path = baseUrl + subdirs[0] + '/index.html';
|
||||
} catch (error) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
segments: pathSegments,
|
||||
finalPath: path
|
||||
};
|
||||
|
||||
return { segments: pathSegments, finalPath: path };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,10 +159,10 @@ export class NavigationManager {
|
||||
async buildCollapsedTreeItem(collapsedPath, depth, currentPath, maxDepth) {
|
||||
const indent = ' '.repeat(depth);
|
||||
const arrow = depth === 0 ? '' : '└─ ';
|
||||
|
||||
|
||||
const displayName = collapsedPath.segments.map(seg => seg.name).join(' / ');
|
||||
const finalPath = collapsedPath.finalPath;
|
||||
|
||||
|
||||
let totalItems = 0;
|
||||
let subdirs = [];
|
||||
try {
|
||||
@@ -176,33 +170,25 @@ export class NavigationManager {
|
||||
const htmlContent = await response.text();
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(htmlContent, 'text/html');
|
||||
|
||||
const subdirElements = doc.querySelectorAll('h2 + ul li a');
|
||||
const items = doc.querySelectorAll('.grid-item');
|
||||
totalItems = items.length + subdirElements.length;
|
||||
|
||||
subdirs = Array.from(subdirElements);
|
||||
} catch (error) {
|
||||
// Handle error case
|
||||
}
|
||||
|
||||
|
||||
const data = this.extractPageData(doc);
|
||||
totalItems = data.itemCount + data.subdirs.length;
|
||||
subdirs = data.subdirs;
|
||||
} catch (error) {}
|
||||
|
||||
let html = '';
|
||||
if (finalPath === currentPath) {
|
||||
html += `<div class="tree-item">${indent}${arrow}📁 <span class="tree-current">${displayName}</span> (${totalItems} items)</div>`;
|
||||
} else {
|
||||
html += `<div class="tree-item">${indent}${arrow}📁 <a href="${finalPath}" class="tree-link">${displayName}</a> (${totalItems} items)</div>`;
|
||||
}
|
||||
|
||||
for (let i = 0; i < subdirs.length; i++) {
|
||||
const subdir = subdirs[i];
|
||||
const href = subdir.getAttribute('href');
|
||||
if (href) {
|
||||
const baseUrl = finalPath.replace(/\/[^\/]*$/, '/');
|
||||
const subPath = baseUrl + href;
|
||||
html += await this.buildTreeRecursive(subPath, depth + 1, currentPath, maxDepth);
|
||||
}
|
||||
|
||||
const baseUrl = finalPath.replace(/\/[^\/]*$/, '/');
|
||||
for (const subdir of subdirs) {
|
||||
const subPath = baseUrl + subdir + '/index.html';
|
||||
html += await this.buildTreeRecursive(subPath, depth + 1, currentPath, maxDepth);
|
||||
}
|
||||
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user