// grid.js — "Grid mode" plugin for browse. Activated by the // view-mode toggle in the toolbar. Loads the standalone classifier // tool as an iframe scoped to the current directory; the user gets // classifier's full bulk-rename workflow without leaving browse. // // This is a v1 — a future iteration could bundle classifier's // modules directly into browse for tighter integration (shared // state, no iframe chrome). For now the iframe is a clean separation // that preserves classifier's full feature set. // // Iframe src resolution: // - server mode: /classifier.html. classifier is // auto-served at any working/staging/incoming subtree per // zddc-server's apps/availability.go. Outside those locations the // iframe will 404 — we surface a friendly message instead of an // opaque blank page. // - file:// or unknown: show a "switch to server mode for grid" // hint. classifier needs FS-API access; embedding it via file:// // iframe is blocked by browser security. (function () { 'use strict'; var state = window.app.state; var mounted = false; function escapeHtml(s) { return String(s).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"'); } function classifierAvailableHere() { // classifier auto-serves under any path containing a segment // named working / staging / incoming (case-insensitive). // browse mode-toggle should reflect that. var path = (window.location && window.location.pathname) || ''; return /\/(working|staging|incoming)(\/|$)/i.test(path); } function activate() { var host = document.getElementById('gridView'); if (!host) return; if (mounted) return; host.innerHTML = ''; if (state.source !== 'server') { host.innerHTML = '
' + '

Grid mode

' + '

The classifier (bulk ZDDC rename) workflow runs as an embedded' + ' iframe and requires the page be served by zddc-server.

' + '

If you opened this file directly (file://), open the standalone' + ' classifier.html tool instead — it provides the same' + ' workflow against a local folder you pick from the file system.

' + '
'; return; } if (!classifierAvailableHere()) { host.innerHTML = '
' + '

Grid mode

' + '

The classifier (bulk ZDDC rename) workflow auto-serves at' + ' working/, staging/, and' + ' incoming/ URLs. The current page' + ' (' + escapeHtml(window.location.pathname) + ') isn\'t' + ' inside any of those, so classifier isn\'t available here.

' + '

Navigate browse into a working/ or staging/ folder, then' + ' switch to Grid.

' + '
'; return; } // Compute the iframe src: current page's directory + classifier.html. var pathname = window.location.pathname || '/'; if (!pathname.endsWith('/')) { // Strip trailing /.html or similar — keep up to the last "/". var lastSlash = pathname.lastIndexOf('/'); pathname = lastSlash >= 0 ? pathname.substring(0, lastSlash + 1) : '/'; } var src = pathname + 'classifier.html'; host.innerHTML = ''; var frame = document.createElement('iframe'); frame.src = src; frame.title = 'ZDDC Classifier (Grid mode)'; frame.style.cssText = 'width:100%;height:100%;border:0;display:block;' + 'background:var(--bg);'; host.appendChild(frame); mounted = true; } window.app.modules.grid = { activate: activate, // Hook the toggle button visibility / hint to the activation // predicate so users at non-classifier paths see the button // in a disabled state with explanation. Callers run this // after the initial directory is loaded. availableHere: function () { return state.source === 'server' && classifierAvailableHere(); } }; })();