diff --git a/manifest.json b/manifest.json index 08791cc984e8a3c3939a294b00725d11b93b2a2c..d72ae1e32a866eb38c165295c78465a867674813 100644 --- a/manifest.json +++ b/manifest.json @@ -45,8 +45,7 @@ "default_title": "BaLex", "default_panel": "src/sidebar/sidebar.html", "default_icon": { - "16": "src/assets/icons/logo.png", - "48": "src/assets/icons/icon-48.png" + "16": "src/assets/icons/logo.png" } }, diff --git a/src/background/background.js b/src/background/background.js index 241f6e0c98a4b60a670fdeea45d755a5cfe15858..22c5f9ab673e45a02ad22868313a6ae5fbb12b92 100644 --- a/src/background/background.js +++ b/src/background/background.js @@ -37,6 +37,27 @@ browser.storage.onChanged.addListener((changes) => { refreshAllUI(); }); +browser.storage.onChanged.addListener((changes, area) => { + if (area === "local" && changes.accessToken) { + const newToken = changes.accessToken.newValue; + if (newToken) { + browser.storage.local.get("extensionActive").then(({ extensionActive }) => { + if (!extensionActive) { + console.log("Token ajouté, activation automatique de l'extension."); + browser.storage.local.set({ extensionActive: true }); + enableExtensionFeatures(); + browser.runtime.sendMessage({ + action: "updateUI", + extensionActive: true, + isTrackingActive: true, + autoAdd: true + }); + } + }); + } + } +}); + // ───────────────────────────────────────────────────────────────────────────── // Fonctions utilitaires // ───────────────────────────────────────────────────────────────────────────── @@ -90,16 +111,12 @@ async function actuallyOpenLoginPage() { // Déconnecte l'utilisateur async function disconnectFromLexicalDB() { - console.log("🔓 Déconnexion en cours..."); await browser.storage.local.remove("accessToken"); console.log("🔓 Token supprimé avec succès."); - // Réinitialiser les couleurs des lexiques dans le local storage - try { - await browser.storage.local.remove("lexiconColors"); - console.log("Les couleurs des lexiques ont été réinitialisées dans le local storage."); - } catch (error) { - console.error("Erreur lors de la réinitialisation des couleurs :", error); - } + + await browser.storage.local.remove("lexiconColors"); + disableExtensionFeatures(); + setTimeout(async () => { await refreshAllUI(); }, 500); @@ -128,6 +145,19 @@ async function saveToken(token) { } originalTabId = null; } + + // Activer automatiquement l'extension + const { extensionActive } = await browser.storage.local.get("extensionActive"); + if (!extensionActive) { + await browser.storage.local.set({ extensionActive: true }); + enableExtensionFeatures(); + browser.runtime.sendMessage({ + action: "updateUI", + extensionActive: true, + isTrackingActive: true, + autoAdd: true + }); + } await refreshAllUI(); } @@ -192,10 +222,6 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => { // Web Navigation : Injection de scripts et récupération du token // ───────────────────────────────────────────────────────────────────────────── browser.webNavigation.onCompleted.addListener(async (details) => { - if (!isExtensionActive) { - console.log("🚫 Extension désactivée, aucune injection script."); - return; - } const url = new URL(details.url); // Injection d'un popup d'instruction sur la page de login @@ -339,14 +365,14 @@ async function disableExtensionFeatures() { browser.runtime.sendMessage({ action: "updateUI", autoAdd: false, - isTrackingActive: false + isTrackingActive: false, + areStatsActive: false }); - const { extensionActive } = await browser.storage.local.get("extensionActive"); - if (extensionActive) { - console.log("🛑 Fermeture de la barre latérale..."); - browser.sidebarAction.close(); - } + // Fermeture de la barre latérale + console.log("🛑 Fermeture de la barre latérale..."); + browser.sidebarAction.close(); + } // === 4. Fonction pour activer les fonctionnalités de l'extension === @@ -355,10 +381,11 @@ async function enableExtensionFeatures() { browser.runtime.sendMessage({ action: "updateUI", autoAdd: true, - isTrackingActive: true + isTrackingActive: true, + areStatsActive: true }); - - + + getOrCreateWhiteBox(); } diff --git a/src/popup/popup.js b/src/popup/popup.js index 177ca54935c6ac7fb7f7147fd8625241d423dbfb..ee029bc2b388327351c5e98bc5626abd62f86412 100644 --- a/src/popup/popup.js +++ b/src/popup/popup.js @@ -15,33 +15,15 @@ async function updateConnectionButton() { } } -// === 2. Écoute des messages depuis background.js === -browser.runtime.onMessage.addListener(async (message) => { - if (message.action === "updateUI") { - console.log("📩 Mise à jour reçue : État connecté :", message.isLoggedIn); - console.log("🔄 Actualisation du menu de l'extension déclenchée."); - updateConnectionButton(); - updateOptionsUI(); - updateLanguageSelection(); - updateSidebarUI(); - } - - if (message.action === "collapseSidebar") { - collapseSidebar(); - } else if (message.action === "expandSidebar") { - expandSidebar(); - } -}); - -// === 3. Mise à jour dynamique de la sélection des langues === +// === 2. Mise à jour dynamique de la sélection des langues === async function updateLanguageSelection() { const languageSelection = document.getElementById("language-selection"); languageSelection.innerHTML = "<p id='loading-languages' style='color: gray;'>Chargement...</p>"; const { accessToken } = await browser.storage.local.get("accessToken"); if (!accessToken) { - languageSelection.innerHTML = "<p style='color: red;'>Veuillez vous connecter.</p>"; - return; + languageSelection.innerHTML = "<p style='color: red;'>Veuillez vous connecter.</p>"; + return; } const lexicons = await getLexicons(accessToken); @@ -53,32 +35,32 @@ async function updateLanguageSelection() { languageSelection.innerHTML = ""; // Suppression du message de chargement if (userLanguages.length === 0) { - languageSelection.innerHTML = "<p style='color: red;'>Aucun lexique personnel trouvé.</p>"; - return; + languageSelection.innerHTML = "<p style='color: red;'>Aucun lexique personnel trouvé.</p>"; + return; } userLanguages.forEach(lang => { - const langButton = document.createElement("div"); - langButton.classList.add("lang-option"); - langButton.textContent = lang.toUpperCase(); - langButton.dataset.value = lang; - - // Vérifier si la langue est suivie et ajouter la classe `selected` - if (trackedLanguages && trackedLanguages.includes(lang)) { - langButton.classList.add("selected"); - } + const langButton = document.createElement("div"); + langButton.classList.add("lang-option"); + langButton.textContent = lang.toUpperCase(); + langButton.dataset.value = lang; + + // Vérifier si la langue est suivie et ajouter la classe `selected` + if (trackedLanguages && trackedLanguages.includes(lang)) { + langButton.classList.add("selected"); + } - langButton.addEventListener("click", () => { - langButton.classList.toggle("selected"); - }); + langButton.addEventListener("click", () => { + langButton.classList.toggle("selected"); + }); - languageSelection.appendChild(langButton); + languageSelection.appendChild(langButton); }); console.log("✅ Sélection des langues mise à jour avec :", userLanguages); } -// === 4. Gestion de l'affichage des boutons des statistiques et des options utilisateur === +// === 3. Gestion de l'affichage des options utilisateur et des statistiques === async function updateOptionsUI() { const { accessToken } = await browser.storage.local.get("accessToken"); const isLoggedIn = !!accessToken; @@ -93,64 +75,62 @@ async function updateOptionsUI() { // Masquer l'option "Ajout Automatique" si l'utilisateur n'est pas connecté if (autoAddContainer) { - autoAddContainer.style.display = isLoggedIn ? "block" : "none"; + autoAddContainer.style.display = isLoggedIn ? "block" : "none"; } // Charger les préférences utilisateur - const { isTrackingActive, autoAdd, trackedLanguages, threshold } = await browser.storage.local.get([ - "isTrackingActive", - "autoAdd", - "trackedLanguages", - "threshold" + const { isTrackingActive, autoAdd, threshold } = await browser.storage.local.get([ + "isTrackingActive", + "autoAdd", + "threshold" ]) || { isTrackingActive: false }; - // Mettre à jour le bouton des statistiques + // Mettre à jour le bouton des statistiques et le bloc associé if (toggleStatsBtn) { - toggleStatsBtn.textContent = isTrackingActive ? "Désactiver les statistiques" : "Activer les statistiques"; + toggleStatsBtn.textContent = isTrackingActive ? "Désactiver les statistiques" : "Activer les statistiques"; } if (statsOptions) { - statsOptions.classList.toggle("hidden", !isTrackingActive); + statsOptions.classList.toggle("hidden", !isTrackingActive); } if (isLoggedIn) { - if (autoAddCheckbox) { - autoAddCheckbox.checked = autoAdd || false; - } - if (thresholdInput && threshold !== undefined) { - thresholdInput.value = threshold; - } - - if (autoAddOptions) { - autoAddOptions.classList.toggle("hidden", !autoAdd); - } - if (saveOptionsBtn) { - saveOptionsBtn.classList.toggle("hidden", !autoAdd); - } + if (autoAddCheckbox) { + autoAddCheckbox.checked = autoAdd || false; + } + if (thresholdInput && threshold !== undefined) { + thresholdInput.value = threshold; + } + if (autoAddOptions) { + autoAddOptions.classList.toggle("hidden", !autoAdd); + } + if (saveOptionsBtn) { + saveOptionsBtn.classList.toggle("hidden", !autoAdd); + } } else { - if (autoAddCheckbox) { - autoAddCheckbox.checked = false; - } - if (autoAddOptions) { - autoAddOptions.classList.add("hidden"); - } - if (saveOptionsBtn) { - saveOptionsBtn.classList.add("hidden"); - } + if (autoAddCheckbox) { + autoAddCheckbox.checked = false; + } + if (autoAddOptions) { + autoAddOptions.classList.add("hidden"); + } + if (saveOptionsBtn) { + saveOptionsBtn.classList.add("hidden"); + } } } - -// === 5. Gestion des événements utilisateur === +// === 4. Gestion des événements utilisateur === document.getElementById("toggleStatsBtn").addEventListener("click", async () => { - const newState = !(await browser.storage.local.get("isTrackingActive")).isTrackingActive; + const current = await browser.storage.local.get("isTrackingActive"); + const newState = !current.isTrackingActive; await browser.storage.local.set({ isTrackingActive: newState }); if (!newState) { - await browser.storage.local.set({ autoAdd: false }); - document.getElementById("auto-add").checked = false; - document.getElementById("auto-add-options").classList.add("hidden"); - document.getElementById("save-options").classList.add("hidden"); + await browser.storage.local.set({ autoAdd: false }); + document.getElementById("auto-add").checked = false; + document.getElementById("auto-add-options").classList.add("hidden"); + document.getElementById("save-options").classList.add("hidden"); } document.getElementById("toggleStatsBtn").textContent = newState ? "Désactiver les statistiques" : "Activer les statistiques"; @@ -159,8 +139,8 @@ document.getElementById("toggleStatsBtn").addEventListener("click", async () => browser.runtime.sendMessage({ command: "toggle-stats", isActive: newState }); if (newState) { - console.log("[Popup] Demande d'initialisation de Pyodide..."); - browser.runtime.sendMessage({ command: "init-pyodide" }); + console.log("[Popup] Demande d'initialisation de Pyodide..."); + browser.runtime.sendMessage({ command: "init-pyodide" }); } }); @@ -170,7 +150,7 @@ document.getElementById("auto-add").addEventListener("change", async () => { document.getElementById("save-options").classList.toggle("hidden", !isChecked); if (!isChecked) { - await browser.storage.local.set({ autoAdd: false }); + await browser.storage.local.set({ autoAdd: false }); } }); @@ -178,61 +158,71 @@ document.getElementById("save-options").addEventListener("click", async () => { const autoAdd = document.getElementById("auto-add").checked; const threshold = parseInt(document.getElementById("threshold").value, 10); const selectedLanguages = Array.from(document.querySelectorAll("#language-selection .lang-option.selected")) - .map(option => option.dataset.value); + .map(option => option.dataset.value); await browser.storage.local.set({ - autoAdd, - threshold, - trackedLanguages: selectedLanguages + autoAdd, + threshold, + trackedLanguages: selectedLanguages }); console.log("Options sauvegardées :", { autoAdd, threshold, trackedLanguages: selectedLanguages }); }); -// === 6. Gestion de l'activation/désactivation de l'extension === +// === 5. Gestion de l'activation/désactivation de l'extension === async function updateExtensionToggleButton() { const { extensionActive } = await browser.storage.local.get("extensionActive") || { extensionActive: true }; const toggleButton = document.getElementById("toggleExtensionBtn"); if (toggleButton) { - toggleButton.textContent = extensionActive ? "Désactiver l'extension" : "Activer l'extension"; + toggleButton.textContent = extensionActive ? "Désactiver l'extension" : "Activer l'extension"; - if (!toggleButton.dataset.listenerAdded) { - toggleButton.addEventListener("click", handleToggleExtension); - toggleButton.dataset.listenerAdded = "true"; - } + if (!toggleButton.dataset.listenerAdded) { + toggleButton.addEventListener("click", handleToggleExtension); + toggleButton.dataset.listenerAdded = "true"; + } } else { - console.error("Le bouton d'activation de l'extension n'a pas été trouvé."); + console.error("Le bouton d'activation de l'extension n'a pas été trouvé."); } } -// Fonction de gestion du clic sur le bouton -async function handleToggleExtension() { +// Fonction de gestion du clic sur le bouton d'activation/désactivation +function handleToggleExtension(event) { + // Pour que l'appel à browser.sidebarAction.close() soit autorisé, + // il doit être déclenché directement dans ce gestionnaire + // Nous fermons la sidebar immédiatement si l'extension est activée. + browser.storage.local.get("extensionActive").then(({ extensionActive }) => { + if (extensionActive) { + browser.sidebarAction.close(); + } + // Ensuite, procéder à la mise à jour de l'état. + proceedToggleExtension(); + }); +} + +async function proceedToggleExtension() { const { extensionActive } = await browser.storage.local.get("extensionActive"); const newState = !extensionActive; await browser.storage.local.set({ extensionActive: newState }); - document.getElementById("toggleExtensionBtn").textContent = newState ? "Désactiver l'extension" : "Activer l'extension"; + const toggleButton = document.getElementById("toggleExtensionBtn"); + if (toggleButton) { + toggleButton.textContent = newState ? "Désactiver l'extension" : "Activer l'extension"; + } + + // Envoi du message vers le background pour mettre à jour les fonctionnalités browser.runtime.sendMessage({ action: "toggleExtension", isActive: newState }); + // Ouvrir la sidebar si l'extension est activée, sinon elle reste fermée. if (newState) { - browser.sidebarAction.open(); - } else { - browser.sidebarAction.close(); + browser.sidebarAction.open(); } showNotification(`Extension ${newState ? "activée" : "désactivée"}.`); } -// === 7. Initialisation === -document.addEventListener("DOMContentLoaded", async () => { - await updateConnectionButton(); - await updateOptionsUI(); - await updateLanguageSelection(); - await updateExtensionToggleButton(); -}); -// === Fonction pour mettre à jour l'UI du popup === +// === 6. Fonction pour mettre à jour l'UI du popup en fonction d'un message === async function updatePopupUI(message) { console.log("🔄 Mise à jour du popup avec :", message); @@ -241,56 +231,78 @@ async function updatePopupUI(message) { const autoAddOptions = document.getElementById("auto-add-options"); if (message.isTrackingActive !== undefined) { - if (statsOptions) { - statsOptions.classList.toggle("hidden", !message.isTrackingActive); - } else { - console.warn("âš ï¸ Ã‰lément #stats-options introuvable."); - } + if (statsOptions) { + statsOptions.classList.toggle("hidden", !message.isTrackingActive); + } else { + console.warn("âš ï¸ Ã‰lément #stats-options introuvable."); + } } if (message.autoAdd !== undefined) { - if (autoAddCheckbox) { - autoAddCheckbox.checked = message.autoAdd; - } else { - console.warn("âš ï¸ Ã‰lément #auto-add introuvable."); - } - - if (autoAddOptions) { - autoAddOptions.classList.toggle("hidden", !message.autoAdd); - } else { - console.warn("âš ï¸ Ã‰lément #auto-add-options introuvable."); - } + if (autoAddCheckbox) { + autoAddCheckbox.checked = message.autoAdd; + } else { + console.warn("âš ï¸ Ã‰lément #auto-add introuvable."); + } + + if (autoAddOptions) { + autoAddOptions.classList.toggle("hidden", !message.autoAdd); + } else { + console.warn("âš ï¸ Ã‰lément #auto-add-options introuvable."); + } } const toggleButton = document.getElementById("toggleExtensionBtn"); - if (toggleButton) { - toggleButton.textContent = message.isTrackingActive ? "Désactiver l'extension" : "Activer l'extension"; - } + if (toggleButton && message.extensionActive !== undefined) { + toggleButton.textContent = message.extensionActive ? "Désactiver l'extension" : "Activer l'extension"; + } } -browser.runtime.onMessage.addListener((message) => { +// === 7. Écoute des messages depuis le background === +browser.runtime.onMessage.addListener(async (message) => { console.log("📩 Message reçu dans popup.js :", message); if (message.action === "updateUI") { - console.log("🔄 Mise à jour de l'UI du popup..."); - updatePopupUI(message); + console.log("🔄 Mise à jour de l'UI du popup..."); + await updateConnectionButton(); + await updateOptionsUI(); + await updateLanguageSelection(); + updatePopupUI(message); + } else if (message.action === "showNotification") { + showNotification(message.text); } }); -// === Fonction pour gérer la notification d'activation/désactivation === +browser.storage.onChanged.addListener((changes, area) => { + if (area === "local" && changes.accessToken) { + updateConnectionButton(); + updateExtensionToggleButton(); + } +}); + + +// === 8. Fonction pour gérer la notification d'activation/désactivation === function showNotification(message) { const notificationBox = document.getElementById("extension-notification"); const notificationText = document.getElementById("notification-text"); const closeButton = document.getElementById("close-notification"); if (notificationBox && notificationText && closeButton) { - notificationText.textContent = message; - notificationBox.classList.remove("hidden"); + notificationText.textContent = message; + notificationBox.classList.remove("hidden"); - closeButton.addEventListener("click", () => { - notificationBox.classList.add("hidden"); - }, { once: true }); + closeButton.addEventListener("click", () => { + notificationBox.classList.add("hidden"); + }, { once: true }); } else { - console.error("⌠Impossible d'afficher la notification : élément manquant."); + console.error("⌠Impossible d'afficher la notification : élément manquant."); } } + +// === 9. Initialisation lors du DOMContentLoaded === +document.addEventListener("DOMContentLoaded", async () => { + await updateConnectionButton(); + await updateOptionsUI(); + await updateLanguageSelection(); + await updateExtensionToggleButton(); +}); diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js index c8857fa00d8b83bd71786cc497cf572e56b9cfb1..1da38e8fd16e8a19f8f59a52407abbf65c5da5f4 100644 --- a/src/sidebar/sidebar.js +++ b/src/sidebar/sidebar.js @@ -3,8 +3,7 @@ console.log( "🌠Vérification API browser :", typeof browser !== "undefined" ? "✅ Disponible" : "⌠Non disponible" ); -console.log("getLexicons type:", typeof getLexicons); -console.log("window.getLexicons type:", typeof window.getLexicons); + // ───────────────────────────────────────────────────────────────────────────── // â–Œ Variables globales