/**
* 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': '
',
'edit': '
',
'delete': '
',
'save': '
',
'upload': '📤',
'download': '📥',
'image': '
',
'file': '📄',
'pdf': '📕',
'link': '🔗',
'refresh': '🔄',
'search': '🌍',
'settings': '
',
'close': '
',
'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()}`);
})();