ZDDC/mdedit/js/utils.js
ZDDC c95f07966d feat(tools,build): in-flight HTML-tool reworks and build-infra updates
Bundles a stretch of in-progress work across the SPA tools so the
tree returns to a coherent shippable state ahead of cutting a new
zddc-server stable image:

- landing: substantial rework of the project picker (sortable/filterable
  table, presets refactor, ?projects= filter, ?v= channel propagation,
  loading/error states)
- archive: presets cleanup, source.js refactor, filtering/url-state
  alignment with the landing page
- mdedit: file-system module split, resizer, file-tree improvements,
  base/toc styling tweaks
- transmittal/classifier: small template touch-ups for shared chrome
- shared: build-lib.sh helpers, new favicon.svg
- bootstrap, build.sh: pick up the channel-aware install/track zip
  generation
- tests: new landing.spec.js, expanded archive/mdedit/build-label specs
- docs: CLAUDE.md picks up the zddc-server section and freshens the
  alpha-build exception note
- regenerated artifacts: install.zip, track-{alpha,beta,stable}.zip,
  *_alpha.html — these are produced by `sh build.sh` and per project
  convention are committed alongside the source changes

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:52:27 -05:00

113 lines
2.6 KiB
JavaScript

/**
* Utility functions
*/
/**
* HTML-escape a string for safe insertion into innerHTML.
*/
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text == null ? '' : String(text);
return div.innerHTML;
}
/**
* Debounce function calls
* @param {Function} func - Function to debounce
* @param {number} wait - Wait time in milliseconds
* @returns {Function} Debounced function
*/
function debounce(func, wait) {
let timeout;
return function () {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), wait);
};
}
/**
* Get file type icon based on file extension
* @param {string} fileName - Name of the file
* @returns {string} Emoji icon for the file type
*/
function getFileTypeIcon(fileName) {
const extension = zddc.splitExtension(fileName).extension;
const iconMap = {
// Documents
'md': '📝',
'markdown': '📝',
'txt': '📄',
'rtf': '📄',
'doc': '📘',
'docx': '📘',
'odt': '📘',
// Web files
'html': '🌐',
'htm': '🌐',
'css': '🎨',
'js': '⚡',
'json': '📋',
'xml': '📊',
'yaml': '⚙️',
'yml': '⚙️',
// PDFs and presentations
'pdf': '📕',
'ppt': '📊',
'pptx': '📊',
'odp': '📊',
// Spreadsheets
'xls': '📗',
'xlsx': '📗',
'csv': '📊',
'ods': '📗',
// Images
'png': '🖼️',
'jpg': '🖼️',
'jpeg': '🖼️',
'gif': '🖼️',
'svg': '🖼️',
'webp': '🖼️',
'bmp': '🖼️',
// Archives
'zip': '📦',
'rar': '📦',
'tar': '📦',
'gz': '📦',
'7z': '📦',
// Code files
'py': '🐍',
'java': '☕',
'cpp': '⚙️',
'c': '⚙️',
'h': '⚙️',
'php': '🔧',
'rb': '💎',
'go': '🔵',
'rs': '🦀',
'swift': '🧡',
'kt': '💜',
// Configuration
'ini': '⚙️',
'conf': '⚙️',
'cfg': '⚙️',
'env': '⚙️',
// Other
'log': '📃',
'sql': '🗄️',
'db': '🗄️',
'sqlite': '🗄️',
};
return iconMap[extension] || '📄';
}