// grid.js — in-pane tool embed for browse (the browse-as-shell bridge; see // ARCHITECTURE.md's ADR). Loads a heavy, full-page tool as an iframe scoped to // the current directory so the user gets that tool's full workflow without // leaving the browse shell. browse stays the top-level app; the cascade's // default_tool decides which tool embeds here. // // Availability: the cascade decides — `state.scopeDefaultTool` (the // X-ZDDC-Default-Tool header) must name one of the EMBEDDABLE full-page tools: // classifier (archive//incoming/), transmittal (…/staging/), archive // (the archive index). tables/forms embed in the preview pane instead // (table-leaf / form view); landing/browse don't self-embed. Operators extend // by setting default_tool on a dir — no code change. Iframe src: // /.html. Server mode only (file:// has no server). (function () { 'use strict'; var state = window.app.state; var mounted = false; // Full-page tools that embed in the gridView pane when they're the dir's // default_tool. (tables/form embed in the preview pane; landing/browse are // not in-pane embeds.) var EMBEDDABLE = { classifier: 1, transmittal: 1, archive: 1 }; // The cascade-resolved default tool for the current dir when it's an // embeddable full-page tool; "" otherwise. function embedToolHere() { var t = state.scopeDefaultTool; return (t && EMBEDDABLE[t]) ? t : ''; } function activate() { var host = document.getElementById('gridView'); if (!host) return; if (mounted) return; var tool = embedToolHere(); if (state.source !== 'server' || !tool) return; // Compute the iframe src: current page's directory + .html. var pathname = window.location.pathname || '/'; if (!pathname.endsWith('/')) { var lastSlash = pathname.lastIndexOf('/'); pathname = lastSlash >= 0 ? pathname.substring(0, lastSlash + 1) : '/'; } var src = pathname + tool + '.html'; host.innerHTML = ''; var frame = document.createElement('iframe'); frame.src = src; frame.title = 'ZDDC ' + tool; frame.style.cssText = 'width:100%;height:100%;border:0;display:block;' + 'background:var(--bg);'; host.appendChild(frame); mounted = true; } // When the user navigates between scopes (client-side rescope on // dblclick), the iframe needs to be reloaded for the new path. // Callers reset before re-activating. function reset() { mounted = false; var host = document.getElementById('gridView'); if (host) host.innerHTML = ''; } window.app.modules.grid = { activate: activate, reset: reset, // Hook for events.js's view-mode resolution: is an embeddable tool the // default here? availableHere: function () { return state.source === 'server' && !!embedToolHere(); }, // The embeddable tool name (or "") — lets the shell label the view. toolHere: embedToolHere }; })();