fscalc/webroot/js/utils.js
2025-10-21 20:50:09 +02:00

167 lines
5.1 KiB
JavaScript

// Shared utility functions for the filesystem calculator
export function parseHex(value) {
if (!value) return 0;
let cleanValue = value.toString().trim();
if (cleanValue.startsWith('0x') || cleanValue.startsWith('0X')) {
cleanValue = cleanValue.substring(2);
}
const parsed = parseInt(cleanValue, 16);
return isNaN(parsed) ? null : Math.max(0, parsed);
}
export function formatHex(value) {
if (isNaN(value) || value < 0) {
return '<span class="error">Fehler</span>';
}
return '0x' + Math.floor(value).toString(16).toUpperCase();
}
export function validateInput(fieldId, value) {
const parsedValue = parseHex(value);
const errorElement = document.getElementById(fieldId + '-error');
const inputElement = document.getElementById(fieldId);
if (parsedValue === null && value.trim() !== '') {
errorElement.textContent = 'Ungültiger Hex-Wert';
inputElement.classList.add('error');
return false;
} else {
errorElement.textContent = '';
inputElement.classList.remove('error');
return true;
}
}
export function checkDependencies(deps) {
return deps.every(dep => {
const element = document.getElementById(dep);
return element && element.value.trim() !== '' && validateInput(dep, element.value);
});
}
export function updateResultItem(elementId, value, available, calculation = '') {
const element = document.getElementById(elementId);
if (!element) return;
const resultItem = element.closest('.result-item');
if (available) {
element.innerHTML = formatHex(value);
resultItem.classList.remove('unavailable');
resultItem.classList.add('available');
if (calculation) {
element.setAttribute('data-result-formula', calculation);
}
} else {
element.innerHTML = '-';
resultItem.classList.remove('available');
resultItem.classList.add('unavailable');
element.removeAttribute('data-result-formula');
}
}
export function copyToClipboard(elementId) {
const element = document.getElementById(elementId);
if (!element) return;
const text = element.textContent.trim();
if (text === '-' || text.includes('Fehler')) {
return;
}
navigator.clipboard.writeText(text).then(() => {
const btn = element.parentElement.querySelector('.copy-btn');
if (btn) {
const originalText = btn.textContent;
btn.textContent = '✓';
btn.style.color = '#88cc88';
setTimeout(() => {
btn.textContent = originalText;
btn.style.color = '';
}, 1000);
}
}).catch(err => {
console.error('Fehler beim Kopieren:', err);
});
}
// Tooltip functionality
let tooltip = null;
export function createTooltip() {
if (!tooltip) {
tooltip = document.createElement('div');
tooltip.className = 'tooltip';
tooltip.style.display = 'none';
document.body.appendChild(tooltip);
}
}
export function showTooltipAt(x, y, text) {
createTooltip();
tooltip.innerHTML = text;
tooltip.style.display = 'block';
const tooltipRect = tooltip.getBoundingClientRect();
let left = x + 12; // offset from mouse pointer
let top = y + 12;
if (left + tooltipRect.width > window.innerWidth - 10) {
left = window.innerWidth - tooltipRect.width - 10;
}
if (top + tooltipRect.height > window.innerHeight - 10) {
top = y - tooltipRect.height - 12;
}
if (left < 10) left = 10;
if (top < 10) top = 10;
tooltip.style.left = left + 'px';
tooltip.style.top = top + 'px';
}
export function hideTooltip() {
if (tooltip) {
tooltip.style.display = 'none';
}
}
// Setup tooltip event listeners
export function setupTooltips() {
document.addEventListener('mousemove', function (e) {
if (e.target.classList.contains('result-label')) {
const formula = e.target.getAttribute('data-formula');
if (formula) {
showTooltipAt(e.clientX, e.clientY, `Formel: ${formula}`);
}
} else if (e.target.classList.contains('result-value')) {
const formula = e.target.getAttribute('data-result-formula');
if (formula && formula !== '') {
showTooltipAt(e.clientX, e.clientY, `Berechnung: ${formula}`);
}
} else {
hideTooltip();
}
});
document.addEventListener('mouseout', function (e) {
if (e.target.classList.contains('result-label') || e.target.classList.contains('result-value')) {
hideTooltip();
}
});
document.addEventListener('scroll', hideTooltip);
}
// Setup copy button functionality
export function setupCopyButtons() {
document.addEventListener('click', function (e) {
if (e.target.classList.contains('copy-btn')) {
const resultValue = e.target.parentElement.querySelector('.result-value');
if (resultValue) {
copyToClipboard(resultValue.id);
}
}
});
}