document.addEventListener('DOMContentLoaded', initApp);
function initApp() {
initDOMReferences();
loadErrorData();
initTheme();
initVisibility();
initSearch();
initSeverityFilters();
initFilterChips();
initQueryBuilder();
initSidebar();
filterErrors();
renderResults();
updateSidebar();
handleUrlHash();
window.addEventListener('hashchange', handleUrlHash);
if (DOM.themeToggle) {
DOM.themeToggle.addEventListener('click', toggleTheme);
}
if (DOM.formatToggle) {
DOM.formatToggle.addEventListener('click', toggleSequenceFormat);
}
if (DOM.hamburgerBtn) {
DOM.hamburgerBtn.addEventListener('click', toggleMobileSidebar);
}
}
function toggleMobileSidebar() {
if (DOM.sidebar && DOM.hamburgerBtn) {
DOM.sidebar.classList.toggle('mobile-open');
DOM.hamburgerBtn.classList.toggle('active');
const isOpen = DOM.sidebar.classList.contains('mobile-open');
DOM.hamburgerBtn.setAttribute('aria-expanded', isOpen);
}
}
function handleUrlHash() {
const hash = window.location.hash.slice(1); if (!hash) return;
const error = AppState.errors.find(e => e.hash === hash);
if (!error) {
console.warn('[WaddlingErrors] Error not found for hash:', hash);
return;
}
if (DOM.searchInput) {
DOM.searchInput.value = '*.*.*.*';
AppState.searchQuery = '*.*.*.*';
filterErrors();
renderResults();
}
requestAnimationFrame(() => {
const card = document.getElementById(`error-${hash}`);
if (card) {
card.scrollIntoView({ behavior: 'smooth', block: 'center' });
card.classList.add('highlight');
const sections = card.querySelectorAll('.error-section');
sections.forEach(section => section.classList.add('open'));
setTimeout(() => card.classList.remove('highlight'), 2500);
}
});
}
function loadErrorData() {
if (typeof DATA !== 'undefined') {
console.log('[WaddlingErrors] Loading DATA object:', DATA);
const errorsArray = DATA.errors
? (Array.isArray(DATA.errors) ? DATA.errors : Object.values(DATA.errors))
: [];
AppState.errors = errorsArray.map(normalizeError);
console.log('[WaddlingErrors] Loaded', AppState.errors.length, 'errors');
AppState.hashLookup = DATA['#'] || {};
console.log('[WaddlingErrors] Hash lookup entries:', Object.keys(AppState.hashLookup).length);
AppState.components = DATA.components || {};
AppState.primaries = DATA.primaries || {};
AppState.sequences = DATA.sequences || {};
AppState.severities = DATA.severities || {};
console.log('[WaddlingErrors] Loaded components:', Object.keys(AppState.components).length);
console.log('[WaddlingErrors] Loaded primaries:', Object.keys(AppState.primaries).length);
console.log('[WaddlingErrors] Loaded severities:', Object.keys(AppState.severities).length);
} else if (typeof errorDatabase !== 'undefined') {
console.log('[WaddlingErrors] Using errorDatabase fallback');
AppState.errors = errorDatabase.map(normalizeError);
} else {
console.warn('[WaddlingErrors] No error data found');
AppState.errors = [];
}
}
function normalizeError(error) {
const sevChar = error.code?.charAt(0)?.toUpperCase() || 'I';
const severityMap = {
'E': 'error',
'B': 'blocked',
'C': 'critical',
'W': 'warning',
'H': 'help',
'S': 'success',
'K': 'completed',
'I': 'info',
'T': 'trace'
};
return {
...error,
code: error.code || 'UNKNOWN',
message: error.message || error.msg || '',
description: error.description || error.desc || '',
severity: severityMap[sevChar] || 'info',
visibility: (error.visibility || 'public').toLowerCase(),
hash: error.hash || null,
hints: Array.isArray(error.hints) ? error.hints : [],
related: Array.isArray(error.related) || Array.isArray(error.see_also)
? (error.related || error.see_also)
: [],
tags: Array.isArray(error.tags) ? error.tags : [],
code_example: error.code_example || error.snippet || null,
language: error.language || 'rust',
component: error.component || null,
primary: error.primary || null,
sequence: error.sequence || null,
};
}
window.WaddlingErrors = {
filterErrors,
renderResults,
toggleCard,
copyToClipboard,
showToast,
setCategory,
setTag,
clearFilters,
selectError,
getState: () => AppState
};