var ALL_ENGINES = [
'wikipedia', 'arxiv', 'crossref', 'braveapi',
'qwant', 'duckduckgo', 'github', 'reddit', 'bing'
];
var DEFAULT_PREFS = {
theme: 'system',
engines: ALL_ENGINES.slice(),
safeSearch: 'moderate',
format: 'html'
};
var STORAGE_KEY = 'kafka_prefs';
function loadPrefs() {
var stored = localStorage.getItem(STORAGE_KEY);
var prefs = DEFAULT_PREFS;
if (stored) {
try {
var parsed = JSON.parse(stored);
prefs = {
theme: parsed.theme || DEFAULT_PREFS.theme,
engines: parsed.engines || DEFAULT_PREFS.engines.slice(),
safeSearch: parsed.safeSearch || DEFAULT_PREFS.safeSearch,
format: parsed.format || DEFAULT_PREFS.format
};
} catch (e) {
prefs = DEFAULT_PREFS;
}
}
return prefs;
}
function savePrefs(prefs) {
localStorage.setItem(STORAGE_KEY, JSON.stringify(prefs));
}
function applyTheme(theme) {
if (theme === 'system') {
document.documentElement.removeAttribute('data-theme');
} else {
document.documentElement.setAttribute('data-theme', theme);
}
}
function syncEngineInput(prefs) {
var input = document.getElementById('engines-input');
if (input) {
input.value = prefs.engines.join(',');
}
}
function closePanel() {
var popover = document.getElementById('settings-popover');
var trigger = document.getElementById('settings-trigger');
if (popover) {
popover.setAttribute('data-open', 'false');
}
if (trigger) {
trigger.setAttribute('aria-expanded', 'false');
}
if (trigger) {
trigger.focus();
}
}
function openPanel() {
var popover = document.getElementById('settings-popover');
var trigger = document.getElementById('settings-trigger');
if (popover) {
popover.setAttribute('data-open', 'true');
}
if (trigger) {
trigger.setAttribute('aria-expanded', 'true');
}
var firstFocusable = popover ? popover.querySelector('button, input, select, textarea, a[href], [tabindex]:not([tabindex="-1"])') : null;
if (firstFocusable) {
firstFocusable.focus();
}
}
function escapeHtml(str) {
return str
.replace(/&/g, '&')
.replace(//g, '>');
}
function renderPanel(prefs) {
var themeIcons = { light: '☀️', dark: '🌙', system: '⌨' };
var safeOptions = ['moderate', 'strict', 'off'];
var formatOptions = ['html', 'json', 'csv', 'rss'];
var html = '
';
html += '
Settings
';
// Theme buttons
html += '
';
// Engine checkboxes
html += '
';
html += '
Engine changes apply to your next search.
';
// Safe search dropdown
html += '
';
html += '
';
// Format dropdown
html += '
';
html += '
';
html += '
';
html += '
';
document.body.innerHTML = html;
// Attach listeners to theme buttons
var themeButtons = document.querySelectorAll('input[name="theme"]');
themeButtons.forEach(function(btn) {
btn.addEventListener('click', function() {
var newPrefs = loadPrefs();
newPrefs.theme = btn.value;
savePrefs(newPrefs);
applyTheme(newPrefs.theme);
});
});
// Attach listeners to engine checkboxes
var engineCheckboxes = document.querySelectorAll('input[name="engine"]');
engineCheckboxes.forEach(function(cb) {
cb.addEventListener('change', function() {
var newPrefs = loadPrefs();
if (cb.checked) {
if (newPrefs.engines.indexOf(cb.value) === -1) {
newPrefs.engines.push(cb.value);
}
} else {
newPrefs.engines = newPrefs.engines.filter(function(e) { return e !== cb.value; });
}
savePrefs(newPrefs);
syncEngineInput(newPrefs);
});
});
// Attach listener to safe search dropdown
var safeSelect = document.getElementById('safe-search-select');
if (safeSelect) {
safeSelect.addEventListener('change', function() {
var newPrefs = loadPrefs();
newPrefs.safeSearch = safeSelect.value;
savePrefs(newPrefs);
});
}
// Attach listener to format dropdown
var formatSelect = document.getElementById('format-select');
if (formatSelect) {
formatSelect.addEventListener('change', function() {
var newPrefs = loadPrefs();
newPrefs.format = formatSelect.value;
savePrefs(newPrefs);
});
}
// Attach listener to close button
var closeBtn = document.getElementById('settings-close');
if (closeBtn) {
closeBtn.addEventListener('click', closePanel);
}
}
function initSettings() {
var prefs = loadPrefs();
applyTheme(prefs.theme);
syncEngineInput(prefs);
renderPanel(prefs);
var trigger = document.getElementById('settings-trigger');
var triggerMobile = document.getElementById('settings-trigger-mobile');
function togglePanel() {
var popover = document.getElementById('settings-popover');
if (popover && popover.getAttribute('data-open') === 'true') {
closePanel();
} else {
openPanel();
}
}
if (trigger) {
trigger.addEventListener('click', togglePanel);
}
if (triggerMobile) {
triggerMobile.addEventListener('click', togglePanel);
}
}
// Escape key handler
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape') {
var popover = document.getElementById('settings-popover');
if (popover && popover.getAttribute('data-open') === 'true') {
closePanel();
}
}
});
// Click outside handler
document.addEventListener('click', function(e) {
var popover = document.getElementById('settings-popover');
var trigger = document.getElementById('settings-trigger');
if (popover && popover.getAttribute('data-open') === 'true') {
if (!popover.contains(e.target) && (!trigger || !trigger.contains(e.target))) {
closePanel();
}
}
});
// Focus trap
document.addEventListener('keydown', function(e) {
if (e.key === 'Tab') {
var popover = document.getElementById('settings-popover');
if (popover && popover.getAttribute('data-open') === 'true') {
var focusableElements = popover.querySelectorAll('button, input, select, textarea, a[href], [tabindex]:not([tabindex="-1"])');
var firstEl = focusableElements[0];
var lastEl = focusableElements[focusableElements.length - 1];
if (e.shiftKey && document.activeElement === firstEl) {
e.preventDefault();
lastEl.focus();
} else if (!e.shiftKey && document.activeElement === lastEl) {
e.preventDefault();
firstEl.focus();
}
}
}
});
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initSettings);
} else {
initSettings();
}