Files
breadcrumb-the-shire/web/js/core/app-dom.js
fs d9f07dcd63 fix: web/ quick wins — CSS cleanup, ARIA tabs, and file header comments
CSS:
- Remove duplicate li::before block in app-search.css
- Fix typo: search-reuslt → search-result in app-search.css
- Remove commented-out CSS rules in app-flash.css
- Add descriptive header comment to all 27 CSS component files

JS:
- Complete WAI-ARIA Tabs pattern: generate IDs, add aria-controls on
  tab buttons and aria-labelledby on tab panels (app-tabs.js)
- Add JSDoc header comments to ~33 JS files (core + components)
- Add explanatory block comment to app-boot.js (why classic IIFE)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 22:21:37 +01:00

58 lines
1.8 KiB
JavaScript

/**
* DOM utility helpers — safe element lookup with missing-element warnings and telemetry.
*/
import { telemetry } from './app-telemetry.js';
const warned = new Set();
export const warnOnce = (code, message, details = {}) => {
const normalizedCode = String(code ?? '').trim() || 'UI_WARN';
const normalizedMessage = String(message ?? '').trim();
const key = `${normalizedCode}:${normalizedMessage}`;
if (warned.has(key)) {return;}
warned.add(key);
console.warn(`[${normalizedCode}] ${normalizedMessage}`, details);
const warnMeta = {
source: 'warn_once',
code: normalizedCode,
};
if (details && typeof details === 'object' && !Array.isArray(details)) {
if (typeof details.module === 'string' && details.module.trim() !== '') {
warnMeta.module = details.module.trim();
}
if (typeof details.component === 'string' && details.component.trim() !== '') {
warnMeta.component = details.component.trim();
}
if (typeof details.feature === 'string' && details.feature.trim() !== '') {
warnMeta.feature = details.feature.trim();
}
}
telemetry.capture('frontend.warn_once', {
severity: 'warning',
message: `[${normalizedCode}] ${normalizedMessage}`,
meta: warnMeta,
});
};
export const requireEl = (selector, details = {}) => {
const el = document.querySelector(selector);
if (!el) {
warnOnce('UI_EL_MISSING', `Missing element: ${selector}`, details);
return null;
}
return el;
};
export const requireAll = (selector, details = {}) => {
const list = Array.from(document.querySelectorAll(selector));
if (!list.length) {
warnOnce('UI_EL_MISSING', `Missing elements: ${selector}`, details);
}
return list;
};
export const optionalEl = (selector) => document.querySelector(selector);