diff --git a/src/css/sidebar.css b/src/css/sidebar.css index 51005ac93cae58b459e284c291512931d528b309..c5dba514443538801848e0f07f7c28b733a70dd9 100644 --- a/src/css/sidebar.css +++ b/src/css/sidebar.css @@ -320,11 +320,13 @@ button.lexique-highlight-toggle:hover .tooltip { filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg); transition: filter 0.3s ease-in-out; } -/* Icone active */ .lexique-highlight-toggle.active .feutre-icon, .lexique-highlight-toggle[data-active="true"] .feutre-icon { filter: brightness(0) saturate(100%) invert(83%) sepia(89%) saturate(588%) hue-rotate(360deg); } +.lexique-highlight-toggle:disabled .feutre-icon { + filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg); +} .lexicon-highlight { position: relative; display: inline-block; diff --git a/src/plugin/plugin.js b/src/plugin/plugin.js index ef3fe0fdcac7b365af357c02246e7fe7cc2e3ed3..d63e8f935df029d97706cbc4f4b2063cca8a66a7 100644 --- a/src/plugin/plugin.js +++ b/src/plugin/plugin.js @@ -149,6 +149,9 @@ async function handleAuthToggle() { isTrackingActive: false }); log("Paramètres réinitialisés après déconnexion."); + + notifyAllTabs({ command: "deactivate-highlighting" }); + log("Message envoyé pour désactiver le surlignage"); } await updateExtension(); } @@ -192,6 +195,8 @@ async function handleToggleExtension() { if (!newState) { await browser.storage.local.set({ isTrackingActive: false }); // if (isTrackingActive) window.open("stats.html", "_blank"); //Si on désactive l'analyse, on ouvre la page de stats + notifyAllTabs({ command: "deactivate-highlighting" }); + log("Message envoyé pour désactiver le surlignage"); browser.runtime.sendMessage({ action: "closeSidebarBlocks" }); } diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js index 277e16aa38ff54eaaea195f5da4e1d92d85dcf36..9f6acfe2e6f4b70b72c008410764e198cd32a71f 100644 --- a/src/sidebar/sidebar.js +++ b/src/sidebar/sidebar.js @@ -164,6 +164,20 @@ async function refreshSidebarState() { } } + // Désactivation (ou activation) des boutons de surlignage selon l'état de l'analyse + const highlightButtons = document.querySelectorAll('.lexique-highlight-toggle'); + highlightButtons.forEach(button => { + if (!isLoggedIn || !isAnalysisEnabled) { + button.disabled = true; + button.style.pointerEvents = 'none'; + button.classList.remove('active'); // retire l'état actif si présent + button.dataset.active = "false"; + } else { + button.disabled = false; + button.style.pointerEvents = 'auto'; + } + }); + log("Barre latérale actualisée. Utilisateur connecté :", isLoggedIn); } @@ -336,48 +350,50 @@ async function fetchLexicons() { */ async function displayLexiconsWithCheckbox(lexicons) { const lexiquesContainer = document.getElementById("lexiques"); - // Vérifie si le conteneur des lexiques existe if (!lexiquesContainer) { - console.warn("ï¸ Ã‰lément #lexiques introuvable."); + console.warn("Élément #lexiques introuvable."); return; } // Vide le conteneur avant d'afficher les nouveaux lexiques lexiquesContainer.innerHTML = ""; - // Vérifie si la liste des lexiques est vide if (lexicons.length === 0) { - log("ï¸ Aucun lexique à afficher."); + log("Aucun lexique à afficher."); lexiquesContainer.textContent = "Aucun lexique disponible."; return; } + // Récupère l'état d'activation de l'analyse et le token d'authentification + const { extensionActive, accessToken } = await browser.storage.local.get(["extensionActive", "accessToken"]); + const isAnalysisEnabled = !!extensionActive; + const isLoggedIn = !!accessToken; + // Parcourt chaque lexique pour créer et afficher les éléments correspondants - for (const { lexiconName, lexiconId, active } of lexicons) { - // Vérifie si le lexique est déjà affiché + for (const { lexiconName, lexiconId } of lexicons) { + // Si ce lexique est déjà affiché, on passe au suivant if (lexiquesContainer.querySelector(`div[data-lexicon-id="${lexiconId}"]`)) { continue; } - // Crée un conteneur pour le lexique + // Crée le conteneur principal pour le lexique const lexiqueDiv = document.createElement("div"); lexiqueDiv.className = "lexique-item"; + lexiqueDiv.dataset.lexiconId = lexiconId; - // Récupère la couleur associée au lexique et crée un cercle de couleur + // Crée l'icône de couleur associée au lexique const color = await getColorForLexicon(lexiconId); const circleIcon = createColorCircle(color, 24); - - // Crée un conteneur pour l'icône de couleur const iconDiv = document.createElement("div"); iconDiv.className = "lexique-icon"; iconDiv.appendChild(circleIcon); - // Crée un élément pour le nom du lexique + // Crée le label affichant le nom du lexique const labelSpan = document.createElement("span"); labelSpan.className = "lexique-label"; labelSpan.textContent = lexiconName; - // Conteneur pour la checkbox (avec tooltip) + // Crée le conteneur de la checkbox avec tooltip const checkboxContainer = document.createElement("label"); checkboxContainer.className = "tooltip-container lexique-checkbox-container"; const addCheckbox = document.createElement("input"); @@ -390,23 +406,33 @@ async function displayLexiconsWithCheckbox(lexicons) { checkboxContainer.appendChild(addCheckbox); checkboxContainer.appendChild(checkboxTooltip); - // Conteneur pour le bouton de surlignage (avec tooltip) + // Crée le bouton de surlignage avec tooltip const highlightButton = document.createElement("button"); highlightButton.className = "tooltip-container lexique-highlight-toggle"; - if (active) { - highlightButton.classList.add('active'); - } highlightButton.dataset.lexiconId = lexiconId; - highlightButton.dataset.active = active ? "true" : "false"; + + if (!isAnalysisEnabled || !isLoggedIn) { + highlightButton.disabled = true; + highlightButton.style.pointerEvents = "none"; + highlightButton.classList.remove("active"); + highlightButton.dataset.active = "false"; + } else { + highlightButton.disabled = false; + highlightButton.style.pointerEvents = "auto"; + highlightButton.classList.remove("active"); + highlightButton.dataset.active = "false"; + } + const feutreIcon = document.createElement("img"); feutreIcon.src = "../assets/icons/feutre.png"; feutreIcon.alt = "Feutre"; feutreIcon.className = "feutre-icon"; + const highlightTooltip = document.createElement("span"); highlightTooltip.className = "tooltip"; highlightTooltip.textContent = "Activer/Désactiver le surlignage des mots du lexique"; - // Mise à jour du gestionnaire d'événements pour le bouton de surlignage + // Gestion du clic sur le bouton de surlignage highlightButton.addEventListener("click", async () => { let currentState = highlightButton.dataset.active === "true"; let newState = !currentState; @@ -424,7 +450,7 @@ async function displayLexiconsWithCheckbox(lexicons) { } }); - // Ajoute les éléments au conteneur du lexique + // Assemble les éléments et ajoute le lexique au conteneur highlightButton.appendChild(feutreIcon); highlightButton.appendChild(highlightTooltip); lexiqueDiv.appendChild(iconDiv); @@ -448,7 +474,6 @@ async function displayLexiconsWithCheckbox(lexicons) { tooltip.style.transform = 'translateX(-50%) translateY(-5px)'; const tooltipRect = tooltip.getBoundingClientRect(); - // Ajuste la position du tooltip si elle déborde du menu if (tooltipRect.left < menuRect.left) { const overflowLeft = menuRect.left - tooltipRect.left; tooltip.style.transform = `translateX(calc(-100% + ${overflowLeft}px)) translateY(-5px)`; @@ -460,6 +485,9 @@ async function displayLexiconsWithCheckbox(lexicons) { }, 100); } + + + /** * Met à jour l'affichage des lexiques. */ diff --git a/src/utils/highlighting.js b/src/utils/highlighting.js index b55029a71088bf1fa80bed37e86eeb84d34d761c..f5d2d734e0ea4073fe4599b33eb5ce58c6c396e6 100644 --- a/src/utils/highlighting.js +++ b/src/utils/highlighting.js @@ -51,6 +51,23 @@ browser.runtime.onMessage.addListener((message) => { } }); +// ───────────────────────────────────────────────────────────── +// â–Œ Suppression de tous les surlignages +// ───────────────────────────────────────────────────────────── +/** + * Supprime tous les surlignages de la page + */ +async function removeAllHighlights() { + log("Suppression de tous les surlignages"); + const highlights = document.querySelectorAll('.lexicon-highlight'); + log(`${highlights.length} surlignages à supprimer`); + highlights.forEach(highlight => { + const text = highlight.textContent; + const textNode = document.createTextNode(text); + highlight.parentNode.replaceChild(textNode, highlight); + }); +} + // ───────────────────────────────────────────────────────────── // â–Œ Gestion des événements globaux // ───────────────────────────────────────────────────────────── @@ -59,12 +76,12 @@ browser.runtime.onMessage.addListener((message) => { * @param {Event} event - L'événement visibilitychange */ document.addEventListener('visibilitychange', async () => { - if (document.visibilityState === 'visible' && window.highlightingActive && activeLexiconIds.size > 0) { + if (document.visibilityState === 'visible' && window.highlightingActive && window.activeLexiconIds.size > 0) { log("Page redevenue visible, réinitialisation du surlignage"); - removeAllHighlights(); - await updateLexiconCache(); - highlightVisibleContent(); - attachMutationObserver(); + await removeAllHighlights(); + await window.updateLexiconCache(); + window.highlightVisibleContent(); + window.attachMutationObserver(); } }); /** @@ -72,12 +89,12 @@ document.addEventListener('visibilitychange', async () => { * @param {Event} event - L'événement pageshow */ window.addEventListener('pageshow', async () => { - if (window.highlightingActive && activeLexiconIds.size > 0) { + if (window.highlightingActive && window.activeLexiconIds.size > 0) { log("Page affichée (pageshow), réinitialisation du surlignage"); - removeAllHighlights(); - await updateLexiconCache(); - highlightVisibleContent(); - attachMutationObserver(); + await removeAllHighlights(); + await window.updateLexiconCache(); + window.highlightVisibleContent(); + window.attachMutationObserver(); } }); @@ -123,7 +140,7 @@ log("Initialisation de highlighting.js"); function getLexiconIdFromName(lexiconName) { const match = lexiconName.match(/\[(\d+)\]$/); const id = match ? parseInt(match[1]) : null; - log(`ï¸ Extraction de l'ID depuis '${lexiconName}': ${id}`); + log(`ï¸Extraction de l'ID depuis '${lexiconName}': ${id}`); return id; } @@ -179,7 +196,7 @@ log("Initialisation de highlighting.js"); log("updateLexiconCache - Début avec contexte:", { authToken: !!window.authToken, getAllLexiconWords: !!window.getAllLexiconWords, - activeLexiconIds: Array.from(activeLexiconIds) + activeLexiconIds: Array.from(window.activeLexiconIds) }); let allWords; try { @@ -187,7 +204,7 @@ log("Initialisation de highlighting.js"); throw new Error("Pas de token d'authentification"); } if (typeof window.getAllLexiconWords !== 'function') { - log("ï¸ getAllLexiconWords n'est pas une fonction"); + log("ï¸getAllLexiconWords n'est pas une fonction"); log("Type de getAllLexiconWords:", typeof window.getAllLexiconWords); log("Contenu de window.getAllLexiconWords:", window.getAllLexiconWords); throw new Error("getAllLexiconWords n'est pas disponible"); @@ -201,7 +218,7 @@ log("Initialisation de highlighting.js"); } lexiconWordsCache.clear(); if (Object.keys(allWords).length === 0) { - log("ï¸ Aucun lexique reçu de getAllLexiconWords"); + log("ï¸Aucun lexique reçu de getAllLexiconWords"); return false; } // Traite chaque lexique reçu @@ -218,7 +235,7 @@ log("Initialisation de highlighting.js"); } log(`Traitement du lexique ${lexiconName} (ID: ${lexiconId})`); // Si l'ID du lexique est actif, met à jour le cache - if (activeLexiconIds.has(Number(lexiconId))) { + if (window.activeLexiconIds.has(Number(lexiconId))) { lexiconWordsCache.set(lexiconId, new Set(words)); log(`Lexique ${lexiconId} chargé avec ${words.length} mots`); } @@ -301,9 +318,9 @@ log("Initialisation de highlighting.js"); // Vérifie si un identifiant de lexique a été fourni if (lexiconId) { // Vérifie si le lexique n'est pas déjà actif - if (!activeLexiconIds.has(lexiconId)) { - activeLexiconIds.add(lexiconId); - const activeLexicons = Array.from(activeLexiconIds); + if (!window.activeLexiconIds.has(lexiconId)) { + window.activeLexiconIds.add(lexiconId); + const activeLexicons = Array.from(window.activeLexiconIds); // Sauvegarde les lexiques actifs dans le stockage local await browser.storage.local.set({ activeLexicons }); log("Lexiques actifs sauvegardés:", activeLexicons); @@ -336,10 +353,10 @@ log("Initialisation de highlighting.js"); async function stopHighlighting(lexiconId) { try { if (lexiconId) { - activeLexiconIds.delete(lexiconId); - const activeLexicons = Array.from(activeLexiconIds); + window.activeLexiconIds.delete(lexiconId); + const activeLexicons = Array.from(window.activeLexiconIds); await browser.storage.local.set({ activeLexicons }); - if (activeLexiconIds.size === 0) { + if (window.activeLexiconIds.size === 0) { window.highlightingActive = false; highlightingActive = false; removeAllHighlights(); @@ -352,7 +369,7 @@ log("Initialisation de highlighting.js"); } else { window.highlightingActive = false; highlightingActive = false; - activeLexiconIds.clear(); + window.activeLexiconIds.clear(); removeAllHighlights(); detachMutationObserver(); } @@ -425,7 +442,7 @@ log("Initialisation de highlighting.js"); * @param {Node} textNode - Le nÅ“ud de texte à traiter */ function processTextNode(textNode) { - if (activeLexiconIds.size === 0) { + if (window.activeLexiconIds.size === 0) { log("ï¸ Aucun lexique actif, sortie du processTextNode"); return; } @@ -441,7 +458,7 @@ log("Initialisation de highlighting.js"); const numericId = parseInt(lexiconId); // Convertit l'ID du lexique en nombre log(`Vérification du lexique ${lexiconId} (ID: ${numericId})`); // Vérifie si le lexique est actif - if (activeLexiconIds.has(numericId)) { + if (window.activeLexiconIds.has(numericId)) { log(`Lexique ${lexiconId} actif, ajout de ${words.size} mots`); // Ajoute chaque mot à l'ensemble des mots à rechercher words.forEach(word => allWords.add(word)); @@ -514,23 +531,6 @@ log("Initialisation de highlighting.js"); } } - // ─────────────────────────────── - // â–Œ Suppression de tous les surlignages - // ─────────────────────────────── - /** - * Supprime tous les surlignages de la page - */ - function removeAllHighlights() { - log("Suppression de tous les surlignages"); - const highlights = document.querySelectorAll('.lexicon-highlight'); - log(`${highlights.length} surlignages à supprimer`); - highlights.forEach(highlight => { - const text = highlight.textContent; - const textNode = document.createTextNode(text); - highlight.parentNode.replaceChild(textNode, highlight); - }); - } - // ─────────────────────────────── // â–Œ Gestion des mutations DOM // ─────────────────────────────── @@ -593,7 +593,7 @@ log("Initialisation de highlighting.js"); browser.runtime.onMessage.addListener((message, sender, sendResponse) => { log("Message reçu:", message, "Context:", { highlightingActive, - activeLexiconIds: Array.from(activeLexiconIds), + activeLexiconIds: Array.from(window.activeLexiconIds), hasAuthToken: !!window.authToken, hasGetAllLexiconWords: !!window.getAllLexiconWords }); @@ -621,7 +621,7 @@ log("Initialisation de highlighting.js"); stopHighlighting(message.lexiconId) .then(() => { // Vérifie si aucun lexique n'est actif - if (activeLexiconIds.size === 0) { + if (window.activeLexiconIds.size === 0) { window.highlightingActive = false; } sendResponse(true); @@ -663,6 +663,14 @@ log("Initialisation de highlighting.js"); } } + window.updateLexiconCache = updateLexiconCache; + window.highlightVisibleContent = highlightVisibleContent; + window.attachMutationObserver = attachMutationObserver; + window.detachMutationObserver = detachMutationObserver; + window.startHighlighting = startHighlighting; + window.stopHighlighting = stopHighlighting; + + // Démarrage initial de la restauration de l'état checkAndRestoreHighlightingState();