Skip to content
Snippets Groups Projects

Améliorations du menu de l'extension

Merged Lucie Bader requested to merge menu_extension_v2 into main
38 files
+ 191002
205
Compare changes
  • Side-by-side
  • Inline
Files
38
+ 218
37
@@ -12,14 +12,14 @@ const AUTH_BALEX_URL = "https://prisms.lezinter.net/fr/headquarters/balex";
// ─────────────────────────────────────────────────────────────────────────────
// Logs de démarrage
// ─────────────────────────────────────────────────────────────────────────────
console.log("🚀 ff2BaLex (background) chargé.");
log("🚀 ff2BaLex (background) chargé.");
browser.runtime.onInstalled.addListener((details) => {
console.log("🔔 Extension installée ou mise à jour. Raison :", details.reason);
log("🔔 Extension installée ou mise à jour. Raison :", details.reason);
});
browser.runtime.onStartup.addListener(() => {
console.log("🔄 Extension démarrée (onStartup).");
log("🔄 Extension démarrée (onStartup).");
});
// ─────────────────────────────────────────────────────────────────────────────
@@ -28,15 +28,36 @@ browser.runtime.onStartup.addListener(() => {
browser.storage.onChanged.addListener((changes) => {
if (changes.extensionActive) {
isExtensionActive = changes.extensionActive.newValue;
console.log("✅ Extension activée :", isExtensionActive);
log("✅ Extension activée :", isExtensionActive);
}
if (changes.statsActive) {
areStatsActive = changes.statsActive.newValue;
console.log("📊 Statistiques activées :", areStatsActive);
log("📊 Statistiques activées :", areStatsActive);
}
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) {
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
// ─────────────────────────────────────────────────────────────────────────────
@@ -46,10 +67,94 @@ async function isUserConnected() {
}
async function refreshAllUI() {
console.log("🔄 Rafraîchissement global de l'UI...");
log("🔄 Rafraîchissement global de l'UI...");
browser.runtime.sendMessage({ action: "refreshUI" });
}
// ─────────────────────────────────────────────────────────────────────────────
// Initialisation du WebWorker
// ─────────────────────────────────────────────────────────────────────────────
let worker = null;
function initWorker() {
if (!worker) {
log("[Background] Initialisation du WebWorker...");
try {
worker = new Worker("src/workers/pyodide_worker.js");
worker.onmessage = (event) => {
log("[Background] Message reçu du WebWorker :", event.data);
};
worker.onerror = (error) => {
console.error("[Background] Erreur dans le WebWorker :", error);
};
log("[Background] WebWorker initialisé avec succès.");
} catch (error) {
console.error("[Background] Échec de l'initialisation du WebWorker :", error);
}
}
}
// Initialisation
initWorker();
worker.postMessage({ command: "pyodide-simplemma" });
// ─────────────────────────────────────────────────────────────────────────────
// Écoute des messages de la popup et transmission au WebWorker
// ─────────────────────────────────────────────────────────────────────────────
browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
log("[Background] Message reçu :", message);
if (!worker) {
initWorker();
}
if (message.command === "toggle-stats") {
log(`[Background] Statistiques ${message.isActive ? "activées" : "désactivées"}`);
await browser.storage.local.set({ isTrackingActive: message.isActive });
// Transmettre l'activation des statistiques au WebWorker
worker.postMessage({ command: "toggle-stats", isActive: message.isActive });
}
if (message.command === "pyodide-simplemma") {
log("[Background] Demande d'initialisation de Pyodide et Simplemma...");
worker.postMessage({ command: "pyodide-simplemma" });
}
return true;
});
// ─────────────────────────────────────────────────────────────────────────────
// Écouter les réponses du WebWorker
// ─────────────────────────────────────────────────────────────────────────────
worker.onmessage = (event) => {
log("[Background] Message du WebWorker :", event.data);
// Pyodide et Simplemma prêts : notifier tous les onglets
if (event.data.type === "pyodide-simplemma" && event.data.status === "success") {
browser.tabs.query({}).then((tabs) => {
tabs.forEach((tab) => {
if (!tab.url || (!tab.url.startsWith("https://") && (!tab.url.startsWith("https://")))) {
return;
}
if (tab.url.includes("sidebar.html")) {
return;
}
try {
let response = browser.tabs.sendMessage(tab.id, { command: "pyodide-simplemma-ready" })
if (response && typeof response.then === "function") {
response.then(() => {
}).catch((error) => {
log("[Background] Impossible d'envoyer un message à l'onglet ${tab.id} : ${error}");
});
}
} catch (error) {
log("[Background] Erreur lors de l'envoi d'un message à l'onglet ${tab.id} : ${error}");
}
});
})
}
}
// ─────────────────────────────────────────────────────────────────────────────
// Fonctions d'authentification & de redirection
// ─────────────────────────────────────────────────────────────────────────────
@@ -57,12 +162,11 @@ browser.runtime.onConnect.addListener((port) => {
if (port.name === "auth") {
port.onMessage.addListener(async (message) => {
if (message.action === "toggleAuth") {
console.log("🔄 toggleAuth reçu via port dans le background.");
log("🔄 toggleAuth reçu via port dans le background.");
const isConnected = await isUserConnected();
if (isConnected) {
await disconnectFromLexicalDB();
} else {
// Ouvre directement la page de connexion
actuallyOpenLoginPage();
}
}
@@ -70,36 +174,40 @@ browser.runtime.onConnect.addListener((port) => {
}
});
// Ouvre directement la page de connexion
async function actuallyOpenLoginPage() {
console.log("🔗 Ouverture de la page de connexion.");
log("🔗 Ouverture de la page de connexion.");
// Mémoriser l'onglet actif
const [currentTab] = await browser.tabs.query({ active: true, currentWindow: true });
if (currentTab) {
originalTabId = currentTab.id;
console.log("✅ Onglet courant mémorisé, ID =", originalTabId);
log("✅ Onglet courant mémorisé, ID =", originalTabId);
}
// Ouvre un nouvel onglet pour la page de connexion et l'active
const loginTab = await browser.tabs.create({ url: AUTH_LOGIN_URL, active: true });
loginTabId = loginTab.id;
console.log("✅ Onglet de login créé, ID =", loginTabId);
log("✅ Onglet de login créé, ID =", loginTabId);
// Notifie que l'authentification est en cours
browser.runtime.sendMessage({ action: "authStatusChanged", isLoggedIn: false });
}
// 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);
}
log("🔓 Token supprimé avec succès.");
await browser.storage.local.remove("lexiconColors");
// Désactivation automatique de l'extension
await browser.storage.local.set({ extensionActive: false });
disableExtensionFeatures();
browser.runtime.sendMessage({
action: "updateUI",
extensionActive: false,
isTrackingActive: false,
autoAdd: false
});
setTimeout(async () => {
await refreshAllUI();
}, 500);
@@ -107,13 +215,13 @@ async function disconnectFromLexicalDB() {
// Sauvegarde le token et ferme l'onglet de login si nécessaire
async function saveToken(token) {
console.log("✅ Sauvegarde du token :", token);
log("✅ Sauvegarde du token :", token);
await browser.storage.local.set({ accessToken: token });
if (loginTabId) {
try {
await browser.tabs.remove(loginTabId);
console.log("🗙 Onglet de login fermé après connexion réussie.");
log("🗙 Onglet de login fermé après connexion réussie.");
} catch (err) {
console.warn("Impossible de fermer l'onglet de login :", err);
}
@@ -122,12 +230,25 @@ async function saveToken(token) {
if (originalTabId) {
try {
await browser.tabs.update(originalTabId, { active: true });
console.log("🔙 Retour sur l'onglet initial :", originalTabId);
log("🔙 Retour sur l'onglet initial :", originalTabId);
} catch (err) {
console.warn("Impossible de basculer sur l'onglet initial :", err);
}
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();
}
@@ -135,7 +256,7 @@ async function saveToken(token) {
// Gestion des messages reçus
// ─────────────────────────────────────────────────────────────────────────────
browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
console.log("📩 Message reçu dans background.js :", message);
log("📩 Message reçu dans background.js :", message);
switch (message.action) {
case "toggleAuth": {
@@ -150,7 +271,7 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
}
case "getDefinitionWiki": {
if (message.selectedText && message.selectedText.trim() !== "") {
console.log("🌐 Requête Wiktionnaire pour :", message.selectedText);
log("🌐 Requête Wiktionnaire pour :", message.selectedText);
const definition = await window.fetchWiktionaryDefinition(message.selectedText.trim());
browser.runtime.sendMessage({
action: "fetchWiktionaryDefinitionResponse",
@@ -171,7 +292,7 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
break;
}
case "authStatusChanged": {
console.log("🔄 Mise à jour de l'état d'authentification :", message.isLoggedIn);
log("🔄 Mise à jour de l'état d'authentification :", message.isLoggedIn);
break;
}
case "saveToken": {
@@ -192,30 +313,26 @@ 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
if (url.hostname === "prisms.lezinter.net" && url.pathname === "/fr/login") {
console.log("📘 Injection du popup d'instruction sur la page de login Prisms.");
log("📘 Injection du popup d'instruction sur la page de login Prisms.");
showInstructionPopup(details);
}
// Récupération du token sur la page /balex
if (url.hostname === "prisms.lezinter.net" && url.pathname === "/fr/headquarters/balex") {
console.log("🟢 Page /balex détectée. Tentative de récupération du token.");
log("🟢 Page /balex détectée. Tentative de récupération du token.");
try {
await new Promise(resolve => setTimeout(resolve, 3000));
await browser.tabs.executeScript(details.tabId, {
code: `
(function() {
console.log("🔍 Recherche du token...");
log("🔍 Recherche du token...");
const tokenElement = document.getElementById("accessToken") || document.getElementById("accesToken");
if (tokenElement) {
const token = tokenElement.innerText.trim();
console.log("🔐 Token détecté :", token);
log("🔐 Token détecté :", token);
browser.runtime.sendMessage({ action: "saveToken", token });
} else {
console.error("❌ Token introuvable.");
@@ -236,7 +353,7 @@ browser.webNavigation.onCompleted.addListener(async (details) => {
browser.webRequest.onBeforeRequest.addListener(
function(details) {
if (details.url === "https://prisms.lezinter.net/fr/headquarters/") {
console.log("🚀 Redirection automatique vers /balex.");
log("🚀 Redirection automatique vers /balex.");
return { redirectUrl: AUTH_BALEX_URL };
}
},
@@ -263,7 +380,7 @@ function showInstructionPopup(details) {
popup.style.borderRadius = "10px";
popup.style.boxShadow = "0 2px 10px rgba(0, 0, 0, 0.3)";
popup.style.zIndex = "10000";
popup.style.fontFamily = "Helvetica, sans-serif";
popup.style.fontFamily = "Luciole";
popup.style.fontSize = "14px";
popup.style.width = "300px";
popup.style.textAlign = "center";
@@ -295,3 +412,67 @@ function showInstructionPopup(details) {
`
});
}
// ─────────────────────────────────────────────────────────────────────────────
// Gestion de l'activation/désactivation de l'extension
// ─────────────────────────────────────────────────────────────────────────────
// === 1. Initialisation de l'état de l'extension ===
async function initializeExtensionState() {
const { extensionActive } = await browser.storage.local.get("extensionActive");
if (extensionActive === undefined) {
await browser.storage.local.set({ extensionActive: true }); // Activation par défaut
log("🔄 Initialisation : extension activée par défaut.");
enableExtensionFeatures();
} else {
log(`🔄 État actuel de l'extension : ${extensionActive ? "activée" : "désactivée"}`);
if (extensionActive) {
enableExtensionFeatures();
} else {
disableExtensionFeatures();
}
}
}
// === 2. Gestion de l'activation/désactivation de l'extension ===
browser.runtime.onMessage.addListener(async (message) => {
if (message.action === "toggleExtension") {
log(`🔄 Changement d'état de l'extension : ${message.isActive ? "activée" : "désactivée"}`);
await browser.storage.local.set({ extensionActive: message.isActive });
if (!message.isActive) {
disableExtensionFeatures();
} else {
enableExtensionFeatures();
}
browser.runtime.sendMessage({ action: "updateUI" });
}
});
// === 3. Fonction pour désactiver les fonctionnalités de l'extension ===
async function disableExtensionFeatures() {
log("Désactivation des fonctionnalités de l'extension.");
browser.runtime.sendMessage({
action: "updateUI",
autoAdd: false,
isTrackingActive: false,
areStatsActive: false
});
// Suppression d'éventuelles actions spécifiques à la sidebar
log("Les fonctionnalités de la sidebar ne sont plus utilisées.");
}
// === 4. Fonction pour activer les fonctionnalités de l'extension ===
async function enableExtensionFeatures() {
log("Réactivation des fonctionnalités de l'extension.");
browser.runtime.sendMessage({
action: "updateUI",
autoAdd: true,
isTrackingActive: true,
areStatsActive: true
}).catch(err => {
console.warn("Aucun récepteur pour le message updateUI :", err);
});
}
initializeExtensionState();
Loading