/** * Icon Manager - Gestion des packs d'icônes * Permet de basculer entre emojis, FontAwesome, et icônes personnalisées */ (function() { 'use strict'; const ICON_PACKS = { 'emoji': { name: 'Emojis Unicode', description: 'Emojis colorés par défaut', icons: { 'add': '➕', 'edit': '✏️', 'delete': '🗑️', 'save': '💾', 'upload': '📤', 'download': '📥', 'image': '🖼️', 'file': '📄', 'pdf': '📕', 'link': '🔗', 'refresh': '🔄', 'search': '🌍', 'settings': '⚙️', 'close': '❌', 'check': '✅', 'warning': '⚠️', 'info': 'ℹ️', 'copy': '📋' } }, 'fontawesome-solid': { name: 'FontAwesome Solid', description: 'Icônes FontAwesome pleines (bold)', icons: { 'add': '', 'edit': '', 'delete': '', 'save': '', 'upload': '', 'download': '', 'image': '', 'file': '', 'pdf': '', 'link': '', 'refresh': '', 'search': '', 'settings': '', 'close': '', 'check': '', 'warning': '', 'info': '', 'copy': '' } }, 'fontawesome-regular': { name: 'FontAwesome Regular', description: 'Icônes FontAwesome fines (outline)', icons: { 'add': '', 'edit': '', 'delete': '', 'save': '', 'upload': '', 'download': '', 'image': '', 'file': '', 'pdf': '', 'link': '', 'refresh': '', 'search': '', 'settings': '', 'close': '', 'check': '', 'warning': '', 'info': '', 'copy': '' } }, 'icons8': { name: 'Icons8 PNG', description: 'Icônes Icons8 existantes (PNG)', icons: { 'add': 'Add', 'edit': 'Edit', 'delete': 'Delete', 'save': 'Save', 'upload': '📤', 'download': '📥', 'image': 'Image', 'file': '📄', 'pdf': '📕', 'link': '🔗', 'refresh': '🔄', 'search': '🌍', 'settings': 'Settings', 'close': 'Close', 'check': 'Check', 'warning': '⚠️', 'info': 'ℹ️', 'copy': '📋' } } }; const DEFAULT_PACK = 'emoji'; const STORAGE_KEY = 'benchtools_icon_pack'; const svgCache = new Map(); function normalizeSvg(svgText) { let text = svgText; text = text.replace(/fill="(?!none)[^"]*"/g, 'fill="currentColor"'); text = text.replace(/stroke="(?!none)[^"]*"/g, 'stroke="currentColor"'); return text; } function inlineSvgElement(el) { const src = el.getAttribute('data-svg-src'); if (!src) return; const cached = svgCache.get(src); if (cached) { el.innerHTML = cached; return; } fetch(src) .then(response => { if (!response.ok) { throw new Error(`SVG load failed: ${response.status}`); } return response.text(); }) .then(text => { const normalized = normalizeSvg(text); svgCache.set(src, normalized); el.innerHTML = normalized; }) .catch(error => { console.warn('[IconManager] Failed to inline SVG:', src, error); }); } function inlineSvgIcons(root = document) { const elements = root.querySelectorAll('[data-svg-src]'); elements.forEach(el => inlineSvgElement(el)); } // Icon Manager Object const IconManager = { packs: ICON_PACKS, getCurrentPack: function() { return localStorage.getItem(STORAGE_KEY) || DEFAULT_PACK; }, applyPack: function(packName) { if (!ICON_PACKS[packName]) { console.error(`Icon pack "${packName}" not found`); return false; } localStorage.setItem(STORAGE_KEY, packName); // Dispatch custom event for icon pack change window.dispatchEvent(new CustomEvent('iconPackChanged', { detail: { pack: packName, packName: ICON_PACKS[packName].name } })); return true; }, getIcon: function(iconName, fallback = '?') { const currentPack = this.getCurrentPack(); const pack = ICON_PACKS[currentPack]; if (!pack) { console.warn(`Icon pack "${currentPack}" not found`); return fallback; } return pack.icons[iconName] || fallback; }, getAllPacks: function() { return Object.keys(ICON_PACKS); }, getPackInfo: function(packName) { return ICON_PACKS[packName] || null; }, // Helper pour générer un bouton avec icône createButton: function(iconName, text = '', className = 'btn btn-primary') { const icon = this.getIcon(iconName); const textPart = text ? ` ${text}` : ''; return ``; }, // Helper pour mettre à jour tous les boutons de la page updateAllButtons: function() { // Cette fonction sera appelée après changement de pack // Pour mettre à jour dynamiquement tous les boutons const buttons = document.querySelectorAll('[data-icon]'); buttons.forEach(btn => { const iconName = btn.getAttribute('data-icon'); const iconSpan = btn.querySelector('.btn-icon-wrapper'); if (iconSpan && iconName) { iconSpan.innerHTML = this.getIcon(iconName); } }); inlineSvgIcons(); }, inlineSvgIcons: function(root = document) { inlineSvgIcons(root); } }; // Auto-initialize on load function initializeIcons() { IconManager.updateAllButtons(); // Also call utils.js initializeButtonIcons if available if (window.initializeButtonIcons) { window.initializeButtonIcons(); } } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initializeIcons); } else { initializeIcons(); } // Re-initialize when icon pack changes window.addEventListener('iconPackChanged', function() { setTimeout(initializeIcons, 100); // Small delay to ensure DOM is ready }); // Expose globally window.IconManager = IconManager; // Log initialization console.log(`[IconManager] Initialized with pack: ${IconManager.getCurrentPack()}`); })();