release: v0.0.10 lockstep
All checks were successful
Build + deploy releases / build-and-deploy (push) Successful in 8s

This commit is contained in:
ZDDC 2026-05-03 17:11:46 -05:00
parent 3494053421
commit f5ffd408f2
8 changed files with 46 additions and 17 deletions

View file

@ -1774,7 +1774,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Markdown</span> <span class="app-header__title">ZDDC Markdown</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button> <button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
</div> </div>

View file

@ -2113,7 +2113,7 @@ td[data-field="trackingNumber"] {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Archive</span> <span class="app-header__title">ZDDC Archive</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button> <button id="addDirectoryBtn" class="btn btn-primary">Add Local Directory</button>
<button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;"></button> <button id="refreshHeaderBtn" class="btn btn-secondary hidden" title="Refresh Data" style="font-size:1.1rem;"></button>
@ -5713,7 +5713,9 @@ window.app.modules.filtering = {
<h1>${window.app.modules.app.escapeHtml(file.name)}</h1> <h1>${window.app.modules.app.escapeHtml(file.name)}</h1>
<button class="btn" onclick="downloadFile()">Download</button> <button class="btn" onclick="downloadFile()">Download</button>
</div> </div>
${ext === 'pdf' ? '<iframe src="' + url + '"></iframe>' : '<div id="previewContent"><div class="loading">Loading preview...</div></div>'} ${(ext === 'pdf' || ext === 'html' || ext === 'htm')
? '<iframe src="' + url + '"' + (ext === 'pdf' ? '' : ' sandbox=""') + '></iframe>'
: '<div id="previewContent"><div class="loading">Loading preview...</div></div>'}
<script> <script>
var blobUrl = "${url}"; var blobUrl = "${url}";
var fileName = "${window.app.modules.app.escapeHtml(file.name).replace(/"/g, '\\"')}"; var fileName = "${window.app.modules.app.escapeHtml(file.name).replace(/"/g, '\\"')}";
@ -5755,8 +5757,15 @@ window.app.modules.filtering = {
filePreviewWindow.focus(); filePreviewWindow.focus();
} }
// For non-PDF types, render content into the preview window // For non-PDF / non-HTML types, render content into the
if (ext === 'docx') { // preview window. PDF and HTML are already wired up via the
// <iframe> in the popup's body (see buildPreviewHtml above);
// for HTML this means the page is RENDERED, not shown as
// literal source text. The previewBlobUrl carries the right
// MIME type ('text/html') so the iframe loads natively.
if (ext === 'pdf' || ext === 'html' || ext === 'htm') {
// iframe already wired in popup HTML; nothing to do
} else if (ext === 'docx') {
await renderDocxInWindow(file); await renderDocxInWindow(file);
} else if (ext === 'xlsx' || ext === 'xls') { } else if (ext === 'xlsx' || ext === 'xls') {
await renderXlsxInWindow(file); await renderXlsxInWindow(file);

View file

@ -1376,7 +1376,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Classifier</span> <span class="app-header__title">ZDDC Classifier</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button> <button id="selectDirectoryBtn" class="btn btn-primary">Select Directory</button>
<button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory">Refresh</button> <button id="refreshBtn" class="btn btn-secondary hidden" title="Refresh and rescan directory">Refresh</button>
@ -6781,6 +6781,11 @@ body.help-open .app-header {
switch (previewType) { switch (previewType) {
case 'pdf': case 'pdf':
return `<iframe src="${blobUrl}#view=FitV"></iframe>`; return `<iframe src="${blobUrl}#view=FitV"></iframe>`;
case 'html':
// Render the HTML natively (not as literal text). sandbox=""
// disables scripts / forms / top-level nav / plugins so an
// archived HTML file can't run code in the popup's origin.
return `<iframe src="${blobUrl}" sandbox=""></iframe>`;
case 'image': case 'image':
return `<img src="${blobUrl}" alt="${escapeHtml(file.originalFilename)}" />`; return `<img src="${blobUrl}" alt="${escapeHtml(file.originalFilename)}" />`;
case 'text': case 'text':
@ -6810,6 +6815,10 @@ body.help-open .app-header {
* Get preview type from extension * Get preview type from extension
*/ */
function getPreviewType(ext) { function getPreviewType(ext) {
// HTML is technically in TEXT_EXTENSIONS (used for editor
// syntax-highlighting elsewhere) but for previews we want to
// RENDER it, not show source. Check before the text branch.
if (ext === 'html' || ext === 'htm') return 'html';
if (PDF_EXTENSIONS.includes(ext)) return 'pdf'; if (PDF_EXTENSIONS.includes(ext)) return 'pdf';
if (TIFF_EXTENSIONS.includes(ext)) return 'tiff'; if (TIFF_EXTENSIONS.includes(ext)) return 'tiff';
if (IMAGE_EXTENSIONS.includes(ext)) return 'image'; if (IMAGE_EXTENSIONS.includes(ext)) return 'image';

View file

@ -866,7 +866,7 @@ body {
</g> </g>
</svg> </svg>
<span class="app-header__title">ZDDC Archive</span> <span class="app-header__title">ZDDC Archive</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<div class="header-right"> <div class="header-right">
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)"></button> <button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)"></button>

View file

@ -1774,7 +1774,7 @@ body.help-open .app-header {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Markdown</span> <span class="app-header__title">ZDDC Markdown</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button> <button id="select-directory" class="btn btn-primary" title="Select a Directory">Select Directory</button>
</div> </div>

View file

@ -2210,7 +2210,7 @@ dialog.modal--narrow {
</svg> </svg>
<div class="header-title-group"> <div class="header-title-group">
<span class="app-header__title">ZDDC Transmittal</span> <span class="app-header__title">ZDDC Transmittal</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<div class="app-header__spacer"></div> <div class="app-header__spacer"></div>
<div class="app-header__icons"> <div class="app-header__icons">
@ -7612,9 +7612,18 @@ dialog.modal--narrow {
var safeName = util.escapeHtml(file.name || file.path || 'file'); var safeName = util.escapeHtml(file.name || file.path || 'file');
var safeHref = util.escapeHtmlAttribute(url); var safeHref = util.escapeHtmlAttribute(url);
// PDF and HTML preview natively in an iframe — for HTML this
// means the page is RENDERED (not shown as literal source text);
// the blob's MIME type ('text/html', see getMimeType) tells the
// browser to render. `sandbox=""` on the HTML iframe disables
// all dangerous capabilities (scripts, top-level navigation,
// forms, plugins, popups) since these are arbitrary archived
// files we don't trust to run JS in the parent's origin.
var contentHtml; var contentHtml;
if (ext === 'pdf') { if (ext === 'pdf') {
contentHtml = '<iframe src="' + safeHref + '"></iframe>'; contentHtml = '<iframe src="' + safeHref + '"></iframe>';
} else if (ext === 'html' || ext === 'htm') {
contentHtml = '<iframe src="' + safeHref + '" sandbox=""></iframe>';
} else { } else {
contentHtml = '<div id="previewContent"><div class="loading">Loading preview...</div></div>'; contentHtml = '<div id="previewContent"><div class="loading">Loading preview...</div></div>';
} }
@ -7827,7 +7836,9 @@ dialog.modal--narrow {
previewWindow.focus(); previewWindow.focus();
} }
if (ext === 'docx') { if (ext === 'pdf' || ext === 'html' || ext === 'htm') {
// iframe already wired in popup HTML; nothing more to do
} else if (ext === 'docx') {
await renderDocxInWindow(file); await renderDocxInWindow(file);
} else if (ext === 'xlsx' || ext === 'xls') { } else if (ext === 'xlsx' || ext === 'xls') {
await renderXlsxInWindow(file); await renderXlsxInWindow(file);

View file

@ -1,7 +1,7 @@
# Generated by build.sh — do not edit. One <app>=<build label> per line. # Generated by build.sh — do not edit. One <app>=<build label> per line.
archive=v0.0.9 archive=v0.0.10
transmittal=v0.0.9 transmittal=v0.0.10
classifier=v0.0.9 classifier=v0.0.10
mdedit=v0.0.9 mdedit=v0.0.10
landing=v0.0.9 landing=v0.0.10
form=v0.0.9 form=v0.0.10

View file

@ -722,7 +722,7 @@ body.help-open .app-header {
</g> </g>
</svg> </svg>
<span class="app-header__title" id="form-title">ZDDC Form</span> <span class="app-header__title" id="form-title">ZDDC Form</span>
<span class="build-timestamp">v0.0.9</span> <span class="build-timestamp">v0.0.10</span>
</div> </div>
<div class="header-right"> <div class="header-right">
<button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)"></button> <button id="theme-btn" class="btn btn-secondary" title="Theme: auto (follows OS)" aria-label="Theme: auto (follows OS)"></button>