From b3918c928d19195a463f2547e91ce41d31fbfd01 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 12:47:36 +0100
Subject: [PATCH 01/23] Ajout de mot v1

---
 api.js                             | 52 +++++++++++++++--
 "barre_lat\303\251rale/sidebar.js" | 90 +++++++++++++++++++++++++++++-
 2 files changed, 136 insertions(+), 6 deletions(-)

diff --git a/api.js b/api.js
index c1a046d..43f05dc 100644
--- a/api.js
+++ b/api.js
@@ -17,19 +17,27 @@ document.addEventListener("mouseup", () => {
 // ▌ Fonction utilitaire pour appeler l’API
 // ─────────────────────────────────────────────────────────────────────────────
 /**
- * Effectue une requête API
+ * Effectue une requête API (GET, POST, etc.) avec ou sans body JSON
  * @param {string} url - L'URL de l'API à appeler.
  * @param {string|null} authToken - Le token d'authentification.
  * @param {string} [method='GET'] - La méthode HTTP.
+ * @param {object|null} [data=null] - Les données à envoyer dans le body (pour POST/PUT...).
  * @returns {Promise<any>} - La réponse en JSON.
  * @throws {Error} - En cas d'échec.
  */
-async function callApi(url, authToken = null, method = 'GET') {
+async function callApi(url, authToken = null, method = 'GET', data = null) {
   const headers = { 'Content-Type': 'application/json' };
   if (authToken) headers.Authorization = `Bearer ${authToken}`;
 
+  const fetchOptions = { method, headers };
+
+  if (data) {
+    // Si on veut envoyer un body JSON
+    fetchOptions.body = JSON.stringify(data);
+  }
+
   try {
-    const response = await fetch(url, { method, headers });
+    const response = await fetch(url, fetchOptions);
     if (!response.ok) {
       throw new Error(`❌ Erreur API (${response.status}): ${response.statusText}`);
     }
@@ -40,6 +48,7 @@ async function callApi(url, authToken = null, method = 'GET') {
   }
 }
 
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Récupération des lexiques de l'utilisateur
 // ─────────────────────────────────────────────────────────────────────────────
@@ -174,6 +183,40 @@ async function getWiktionaryDefinition(word) {
   }
 }
 
+// ─────────────────────────────────────────────────────────────────────────────
+// ▌ Ajout d'un mot dans un/des lexique(s)
+// ─────────────────────────────────────────────────────────────────────────────
+/**
+ * Ajoute un mot (selectedWord) dans un ou plusieurs lexiques (lexiconIds).
+ * @param {string} authToken     - Jeton d'authentification (Bearer).
+ * @param {string} selectedWord  - Le mot à ajouter.
+ * @param {number[]} lexiconIds  - Tableau d'IDs de lexiques cibles.
+ * @param {boolean} [force=false] - Paramètre optionnel pour l'API.
+ * @returns {Promise<any>} - La réponse JSON de l'API, ou une exception si échec.
+ */
+async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
+  if (!authToken) {
+    throw new Error("Aucun token d’authentification fourni.");
+  }
+  if (!selectedWord) {
+    throw new Error("Aucun mot n’a été spécifié pour l’ajout.");
+  }
+  if (!Array.isArray(lexiconIds) || lexiconIds.length === 0) {
+    throw new Error("Aucun lexique sélectionné pour l’ajout.");
+  }
+
+  const url = "https://babalex.lezinter.net/api/entry/create"; 
+  const body = {
+    graphy: selectedWord,
+    force,
+    target_lex: lexiconIds
+  };
+
+  return callApi(url, authToken, "POST", body);
+}
+
+
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Exposition des fonctions pour un usage global
 // ─────────────────────────────────────────────────────────────────────────────
@@ -183,4 +226,5 @@ window.getLexicons = getLexicons;
 window.getAllCategoriesLexicons = getAllCategoriesLexicons;
 window.getLexiconEntries = getLexiconEntries;
 window.getAllLexiconWords = getAllLexiconWords;
-window.getWiktionaryDefinition = getWiktionaryDefinition;
\ No newline at end of file
+window.getWiktionaryDefinition = getWiktionaryDefinition;
+window.AddWord = AddWord;
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index b920188..79a2bab 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -190,6 +190,11 @@ async function fetchLexicons() {
   }
 }
 
+/**
+ * Affiche la liste des lexiques avec des checkboxes.
+ * Les checkboxes servent ici à activer/désactiver le surlignage,
+ * mais on va aussi s’en servir pour déterminer où ajouter le mot.
+ */
 function displayLexiconsWithCheckbox(lexicons) {
   const lexiquesContainer = document.getElementById("lexiques");
   if (!lexiquesContainer) {
@@ -202,31 +207,41 @@ function displayLexiconsWithCheckbox(lexicons) {
     lexiquesContainer.textContent = "Aucun lexique disponible.";
     return;
   }
+
   lexicons.forEach(({ lexiconName, lexiconId, active }) => {
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
+
     const iconDiv = document.createElement("div");
     iconDiv.className = "lexique-icon";
     iconDiv.style.backgroundColor = "#ccc";
+
     const labelSpan = document.createElement("span");
     labelSpan.className = "lexique-label";
     labelSpan.textContent = lexiconName;
+
     const checkbox = document.createElement("input");
     checkbox.type = "checkbox";
     checkbox.className = "lexique-checkbox";
     checkbox.checked = active;
+    // On stocke l'ID du lexique dans un attribut data pour le récupérer plus tard
+    checkbox.dataset.lexiconId = lexiconId;
+
+    // Toggle highlight
     checkbox.addEventListener("change", async () => {
       console.log(
         `🔄 Changement de surlignage pour ${lexiconName} (ID: ${lexiconId}): ${
           checkbox.checked ? "activé" : "désactivé"
         }`
       );
+      // On envoie un message au background script pour gérer le highlight
       await browser.runtime.sendMessage({
         action: "toggleLexiconHighlight",
         lexiconId,
         isActive: checkbox.checked,
       });
     });
+
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
     lexiqueDiv.appendChild(checkbox);
@@ -266,6 +281,70 @@ async function handleAuthButtonClick() {
   await refreshSidebarState();
 }
 
+// ─────────────────────────────────────────────────────────────────────────────
+// ▌ Ajout d'un mot au(x) lexique(s)
+// ─────────────────────────────────────────────────────────────────────────────
+/**
+ * Au clic sur le bouton "add-word-button",
+ * on récupère le mot sélectionné (#motSelectionne)
+ * et les lexiques cochés, puis on appelle AddWord.
+ */
+async function handleAddWordClick() {
+  if (!authToken) {
+    console.warn("⚠️ Impossible d’ajouter le mot : pas de token d’authentification.");
+    return;
+  }
+
+  const selectedWordElement = document.getElementById("motSelectionne");
+  const lexiconResultElement = document.getElementById("lexiconResult");
+
+  if (!selectedWordElement) {
+    console.warn("⚠️ Élément #motSelectionne introuvable.");
+    return;
+  }
+
+  const selectedWord = selectedWordElement.textContent.trim();
+  if (!selectedWord || selectedWord === "Aucun mot sélectionné") {
+    console.warn("⚠️ Aucun mot à ajouter.");
+    if (lexiconResultElement) {
+      lexiconResultElement.textContent = "Aucun mot à ajouter.";
+    }
+    return;
+  }
+
+  // On récupère toutes les checkboxes cochées dans #lexiques
+  const checkboxList = document.querySelectorAll("#lexiques .lexique-checkbox:checked");
+  const selectedLexiconIds = Array.from(checkboxList).map((cb) =>
+    parseInt(cb.dataset.lexiconId, 10)
+  );
+
+  if (selectedLexiconIds.length === 0) {
+    console.warn("⚠️ Aucun lexique sélectionné.");
+    if (lexiconResultElement) {
+      lexiconResultElement.textContent = "Veuillez cocher au moins un lexique.";
+    }
+    return;
+  }
+
+  console.log("📦 Ajout du mot :", selectedWord, "dans lexique(s) :", selectedLexiconIds);
+
+  // Appel à la fonction AddWord (définie dans api.js et exposée en window)
+  try {
+    const result = await window.AddWord(authToken, selectedWord, selectedLexiconIds, false);
+    console.log("✅ Réponse d’ajout :", result);
+
+    if (lexiconResultElement) {
+      lexiconResultElement.textContent = "Mot ajouté avec succès !";
+      // Si l’API renvoie plus d’infos, vous pouvez les afficher ici
+    }
+  } catch (error) {
+    console.error("❌ Erreur lors de l’ajout du mot :", error);
+    if (lexiconResultElement) {
+      lexiconResultElement.textContent = "Erreur lors de l’ajout : " + error.message;
+    }
+  }
+}
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Réception des messages
 // ─────────────────────────────────────────────────────────────────────────────
@@ -379,9 +458,16 @@ document.addEventListener("DOMContentLoaded", async () => {
       });
     });
   }
-});
 
-document.addEventListener("DOMContentLoaded", () => {
+  // Bouton "Ajouter au(x) lexique(s)"
+  const addWordButton = document.getElementById("add-word-button");
+  if (addWordButton) {
+    addWordButton.addEventListener("click", handleAddWordClick);
+  } else {
+    console.warn("⚠️ Bouton #add-word-button introuvable dans le DOM.");
+  }
+
+  // Écouteur pour la case à cocher "toggle-definitions"
   const toggleButtons = document.querySelectorAll(".toggle-btn");
   toggleButtons.forEach((btn) => {
     if (!btn.textContent.trim()) {
-- 
GitLab


From 4f6a18eeb13495112d81e367e2b5ea50e860656d Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 14:29:22 +0100
Subject: [PATCH 02/23] Message d'erreur si mot existant dans lexique

---
 "barre_lat\303\251rale/sidebar.js" | 103 +++++++++++++++++++++--------
 1 file changed, 74 insertions(+), 29 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 79a2bab..e885de2 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -209,46 +209,66 @@ function displayLexiconsWithCheckbox(lexicons) {
   }
 
   lexicons.forEach(({ lexiconName, lexiconId, active }) => {
+    // Création du conteneur pour ce lexique
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
 
+    // Optionnel : un élément visuel (icône)
     const iconDiv = document.createElement("div");
     iconDiv.className = "lexique-icon";
     iconDiv.style.backgroundColor = "#ccc";
 
+    // Le label affichant le nom du lexique
     const labelSpan = document.createElement("span");
     labelSpan.className = "lexique-label";
     labelSpan.textContent = lexiconName;
 
-    const checkbox = document.createElement("input");
-    checkbox.type = "checkbox";
-    checkbox.className = "lexique-checkbox";
-    checkbox.checked = active;
-    // On stocke l'ID du lexique dans un attribut data pour le récupérer plus tard
-    checkbox.dataset.lexiconId = lexiconId;
-
-    // Toggle highlight
-    checkbox.addEventListener("change", async () => {
-      console.log(
-        `🔄 Changement de surlignage pour ${lexiconName} (ID: ${lexiconId}): ${
-          checkbox.checked ? "activé" : "désactivé"
-        }`
-      );
-      // On envoie un message au background script pour gérer le highlight
-      await browser.runtime.sendMessage({
-        action: "toggleLexiconHighlight",
-        lexiconId,
-        isActive: checkbox.checked,
-      });
+    // La case à cocher servant à sélectionner le lexique pour l'ajout d'un mot
+    const addCheckbox = document.createElement("input");
+    addCheckbox.type = "checkbox";
+    addCheckbox.className = "lexique-add-checkbox";
+    // On stocke l'ID du lexique dans le dataset pour l'utiliser lors de l'ajout
+    addCheckbox.dataset.lexiconId = lexiconId;
+
+    // Le bouton pour activer/désactiver le surlignage
+    const highlightButton = document.createElement("button");
+    highlightButton.className = "lexique-highlight-toggle";
+    highlightButton.dataset.lexiconId = lexiconId;
+    // Stocke l'état initial dans le dataset ("true" si actif, sinon "false")
+    highlightButton.dataset.active = active ? "true" : "false";
+    // Définition du texte du bouton en fonction de l'état initial
+    highlightButton.textContent = active ? "Désactiver surlignage" : "Activer surlignage";
+
+    // Gestion du clic sur le bouton de surlignage
+    highlightButton.addEventListener("click", async () => {
+      // On récupère l'état courant depuis le dataset
+      let currentState = highlightButton.dataset.active === "true";
+      let newState = !currentState;
+      try {
+        // Envoi d'un message pour demander au background de changer l'état de surlignage
+        await browser.runtime.sendMessage({
+          action: "toggleLexiconHighlight",
+          lexiconId,
+          isActive: newState,
+        });
+        // Mise à jour de l'état stocké et du texte du bouton
+        highlightButton.dataset.active = newState ? "true" : "false";
+        highlightButton.textContent = newState ? "Désactiver surlignage" : "Activer surlignage";
+      } catch (error) {
+        console.error("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
+      }
     });
 
+    // Assemblage de l'élément du lexique
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
-    lexiqueDiv.appendChild(checkbox);
+    lexiqueDiv.appendChild(addCheckbox);
+    lexiqueDiv.appendChild(highlightButton);
     lexiquesContainer.appendChild(lexiqueDiv);
   });
 }
 
+
 function initModal() {
   console.log("initModal appelé");
   const modalOverlay = document.getElementById("modalOverlay");
@@ -313,7 +333,7 @@ async function handleAddWordClick() {
   }
 
   // On récupère toutes les checkboxes cochées dans #lexiques
-  const checkboxList = document.querySelectorAll("#lexiques .lexique-checkbox:checked");
+  const checkboxList = document.querySelectorAll("#lexiques .lexique-add-checkbox:checked");
   const selectedLexiconIds = Array.from(checkboxList).map((cb) =>
     parseInt(cb.dataset.lexiconId, 10)
   );
@@ -326,16 +346,41 @@ async function handleAddWordClick() {
     return;
   }
 
-  console.log("📦 Ajout du mot :", selectedWord, "dans lexique(s) :", selectedLexiconIds);
-
-  // Appel à la fonction AddWord (définie dans api.js et exposée en window)
+  // Vérifier si le mot existe déjà dans l'un des lexiques sélectionnés
+  let definitions = [];
   try {
-    const result = await window.AddWord(authToken, selectedWord, selectedLexiconIds, false);
-    console.log("✅ Réponse d’ajout :", result);
+    definitions = await fetchLexiconDefinitions(selectedWord);
+  } catch (error) {
+    console.error("Erreur lors de la récupération des définitions pour vérification :", error);
+  }
 
+  let exists = false;
+  if (definitions && definitions.length > 0) {
+    for (const def of definitions) {
+      if (selectedLexiconIds.includes(def.lexiconId)) {
+        exists = true;
+        break;
+      }
+    }
+  }
+
+  if (exists) {
+    if (lexiconResultElement) {
+      lexiconResultElement.innerHTML =
+        "Le mot <strong>" + selectedWord + "</strong> existe déjà dans le(s) lexique(s) : " + selectedLexiconIds.join(", ") + ".";
+    }
+    return; 
+  }
+
+  // Procéder à l'ajout dans chaque lexique sélectionné
+  try {
+    for (const lexId of selectedLexiconIds) {
+      const result = await window.AddWord(authToken, selectedWord, [lexId], false);
+      console.log("✅ Réponse d’ajout pour le lexique", lexId, ":", result);
+    }
     if (lexiconResultElement) {
-      lexiconResultElement.textContent = "Mot ajouté avec succès !";
-      // Si l’API renvoie plus d’infos, vous pouvez les afficher ici
+      lexiconResultElement.textContent =
+        "✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans les lexiques : " + selectedLexiconIds.join(", ") + ".";
     }
   } catch (error) {
     console.error("❌ Erreur lors de l’ajout du mot :", error);
-- 
GitLab


From 5c91991d64c85b464f226a5ba94b8ae1dd53b815 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 17:26:00 +0100
Subject: [PATCH 03/23] Correction erreur 500

---
 "barre_lat\303\251rale/sidebar.js" | 69 +++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 24 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index e885de2..6b7e389 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -310,8 +310,9 @@ async function handleAuthButtonClick() {
  * et les lexiques cochés, puis on appelle AddWord.
  */
 async function handleAddWordClick() {
+  // 1) Vérifier la présence du token et du mot
   if (!authToken) {
-    console.warn("⚠️ Impossible d’ajouter le mot : pas de token d’authentification.");
+    console.warn("⚠️ Pas de token d'authentification : impossible d'ajouter le mot.");
     return;
   }
 
@@ -322,7 +323,6 @@ async function handleAddWordClick() {
     console.warn("⚠️ Élément #motSelectionne introuvable.");
     return;
   }
-
   const selectedWord = selectedWordElement.textContent.trim();
   if (!selectedWord || selectedWord === "Aucun mot sélectionné") {
     console.warn("⚠️ Aucun mot à ajouter.");
@@ -332,12 +332,11 @@ async function handleAddWordClick() {
     return;
   }
 
-  // On récupère toutes les checkboxes cochées dans #lexiques
+  // 2) Récupérer les IDs des lexiques sélectionnés (cases à cocher “add-checkbox”)
   const checkboxList = document.querySelectorAll("#lexiques .lexique-add-checkbox:checked");
-  const selectedLexiconIds = Array.from(checkboxList).map((cb) =>
+  const selectedLexiconIds = Array.from(checkboxList).map(cb =>
     parseInt(cb.dataset.lexiconId, 10)
   );
-
   if (selectedLexiconIds.length === 0) {
     console.warn("⚠️ Aucun lexique sélectionné.");
     if (lexiconResultElement) {
@@ -346,7 +345,7 @@ async function handleAddWordClick() {
     return;
   }
 
-  // Vérifier si le mot existe déjà dans l'un des lexiques sélectionnés
+  // 3) Vérifier si le mot existe déjà dans l'un des lexiques sélectionnés
   let definitions = [];
   try {
     definitions = await fetchLexiconDefinitions(selectedWord);
@@ -354,42 +353,64 @@ async function handleAddWordClick() {
     console.error("Erreur lors de la récupération des définitions pour vérification :", error);
   }
 
-  let exists = false;
-  if (definitions && definitions.length > 0) {
+  // Construire un ensemble (ou tableau) des IDs dans lesquels le mot existe déjà
+  const existingLexiconIds = [];
+  if (Array.isArray(definitions)) {
     for (const def of definitions) {
-      if (selectedLexiconIds.includes(def.lexiconId)) {
-        exists = true;
-        break;
+      if (selectedLexiconIds.includes(def.lexiconId) && !existingLexiconIds.includes(def.lexiconId)) {
+        existingLexiconIds.push(def.lexiconId);
       }
     }
   }
 
-  if (exists) {
+  if (existingLexiconIds.length > 0) {
     if (lexiconResultElement) {
       lexiconResultElement.innerHTML =
-        "Le mot <strong>" + selectedWord + "</strong> existe déjà dans le(s) lexique(s) : " + selectedLexiconIds.join(", ") + ".";
+        "Le mot <strong>" + selectedWord + "</strong> existe déjà dans le(s) lexique(s) : " +
+        existingLexiconIds.join(", ") + ".";
     }
     return; 
   }
 
-  // Procéder à l'ajout dans chaque lexique sélectionné
-  try {
-    for (const lexId of selectedLexiconIds) {
+  // 4) Déterminer les lexiques où ajouter le mot (ceux où il n’existe pas)
+  const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.includes(id));
+  if (lexiconsToAdd.length === 0) {
+    // Le mot existe déjà dans tous les lexiques sélectionnés
+    return;
+  }
+
+  // 5) Ajouter le mot dans les lexiques restants
+  let addResults = [];
+  for (const lexId of lexiconsToAdd) {
+    try {
       const result = await window.AddWord(authToken, selectedWord, [lexId], false);
-      console.log("✅ Réponse d’ajout pour le lexique", lexId, ":", result);
+      console.log("✅ Ajout réussi dans le lexique", lexId, ":", result);
+      addResults.push({ lexId, success: true });
+      // Envoyer un message pour rafraîchir l'UI si nécessaire
+      browser.runtime.sendMessage({ action: "refreshUI" });
+    } catch (error) {
+      console.error("❌ Erreur lors de l’ajout dans le lexique", lexId, ":", error);
+      addResults.push({ lexId, success: false, error });
     }
-    if (lexiconResultElement) {
-      lexiconResultElement.textContent =
-        "✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans les lexiques : " + selectedLexiconIds.join(", ") + ".";
+  }
+
+  // 6) Afficher un message récapitulatif
+  if (lexiconResultElement) {
+    let message = "";
+    const successful = addResults.filter(r => r.success).map(r => r.lexId);
+    const failed = addResults.filter(r => !r.success).map(r => r.lexId);
+
+    if (successful.length > 0) {
+      message += "✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans les lexiques : " + successful.join(", ") + ".";
     }
-  } catch (error) {
-    console.error("❌ Erreur lors de l’ajout du mot :", error);
-    if (lexiconResultElement) {
-      lexiconResultElement.textContent = "Erreur lors de l’ajout : " + error.message;
+    if (failed.length > 0) {
+      message += "<br>❌ Échec de l'ajout dans les lexiques : " + failed.join(", ") + ".";
     }
+    lexiconResultElement.innerHTML = message;
   }
 }
 
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Réception des messages
 // ─────────────────────────────────────────────────────────────────────────────
-- 
GitLab


From a5b78ec2c316b110143b318c0736cd90639f32a6 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 18:27:59 +0100
Subject: [PATCH 04/23] Correction beug ajout multiple

---
 api.js                             |  4 +-
 "barre_lat\303\251rale/sidebar.js" | 81 +++++++++++++-----------------
 definitions.js                     |  1 +
 3 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/api.js b/api.js
index 43f05dc..72eb48c 100644
--- a/api.js
+++ b/api.js
@@ -30,9 +30,9 @@ async function callApi(url, authToken = null, method = 'GET', data = null) {
   if (authToken) headers.Authorization = `Bearer ${authToken}`;
 
   const fetchOptions = { method, headers };
-
+  console.log("Envoi de la requête vers :", url);
   if (data) {
-    // Si on veut envoyer un body JSON
+    console.log("Body JSON :", JSON.stringify(data, null, 2));
     fetchOptions.body = JSON.stringify(data);
   }
 
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 6b7e389..c01621b 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -326,26 +326,21 @@ async function handleAddWordClick() {
   const selectedWord = selectedWordElement.textContent.trim();
   if (!selectedWord || selectedWord === "Aucun mot sélectionné") {
     console.warn("⚠️ Aucun mot à ajouter.");
-    if (lexiconResultElement) {
-      lexiconResultElement.textContent = "Aucun mot à ajouter.";
-    }
+    if (lexiconResultElement) lexiconResultElement.textContent = "Aucun mot à ajouter.";
     return;
   }
 
   // 2) Récupérer les IDs des lexiques sélectionnés (cases à cocher “add-checkbox”)
   const checkboxList = document.querySelectorAll("#lexiques .lexique-add-checkbox:checked");
-  const selectedLexiconIds = Array.from(checkboxList).map(cb =>
-    parseInt(cb.dataset.lexiconId, 10)
-  );
+  const selectedLexiconIds = Array.from(checkboxList).map(cb => parseInt(cb.dataset.lexiconId, 10));
+
   if (selectedLexiconIds.length === 0) {
     console.warn("⚠️ Aucun lexique sélectionné.");
-    if (lexiconResultElement) {
-      lexiconResultElement.textContent = "Veuillez cocher au moins un lexique.";
-    }
+    if (lexiconResultElement) lexiconResultElement.textContent = "Veuillez cocher au moins un lexique.";
     return;
   }
 
-  // 3) Vérifier si le mot existe déjà dans l'un des lexiques sélectionnés
+  // 3) Vérifier si le mot existe déjà dans l’un des lexiques sélectionnés
   let definitions = [];
   try {
     definitions = await fetchLexiconDefinitions(selectedWord);
@@ -353,64 +348,60 @@ async function handleAddWordClick() {
     console.error("Erreur lors de la récupération des définitions pour vérification :", error);
   }
 
-  // Construire un ensemble (ou tableau) des IDs dans lesquels le mot existe déjà
-  const existingLexiconIds = [];
+  const existingLexiconIds = new Set();
   if (Array.isArray(definitions)) {
     for (const def of definitions) {
-      if (selectedLexiconIds.includes(def.lexiconId) && !existingLexiconIds.includes(def.lexiconId)) {
-        existingLexiconIds.push(def.lexiconId);
+      if (selectedLexiconIds.includes(def.lexiconId)) {
+        existingLexiconIds.add(def.lexiconId);
       }
     }
   }
 
-  if (existingLexiconIds.length > 0) {
+  // 4) Si le mot existe déjà dans certains lexiques, on les affiche
+  if (existingLexiconIds.size > 0) {
     if (lexiconResultElement) {
       lexiconResultElement.innerHTML =
         "Le mot <strong>" + selectedWord + "</strong> existe déjà dans le(s) lexique(s) : " +
-        existingLexiconIds.join(", ") + ".";
+        Array.from(existingLexiconIds).join(", ") + ".";
     }
-    return; 
   }
 
-  // 4) Déterminer les lexiques où ajouter le mot (ceux où il n’existe pas)
-  const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.includes(id));
+  // 5) Déterminer les lexiques où ajouter le mot
+  const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.has(id));
   if (lexiconsToAdd.length === 0) {
-    // Le mot existe déjà dans tous les lexiques sélectionnés
-    return;
+    return; // Rien à ajouter, tous les lexiques sélectionnés contiennent déjà le mot
   }
 
-  // 5) Ajouter le mot dans les lexiques restants
-  let addResults = [];
-  for (const lexId of lexiconsToAdd) {
-    try {
-      const result = await window.AddWord(authToken, selectedWord, [lexId], false);
-      console.log("✅ Ajout réussi dans le lexique", lexId, ":", result);
-      addResults.push({ lexId, success: true });
-      // Envoyer un message pour rafraîchir l'UI si nécessaire
-      browser.runtime.sendMessage({ action: "refreshUI" });
-    } catch (error) {
-      console.error("❌ Erreur lors de l’ajout dans le lexique", lexId, ":", error);
-      addResults.push({ lexId, success: false, error });
-    }
-  }
+  // 6) Envoi d’une seule requête pour tous les lexiques restants
+  try {
+    console.log(`📡 Envoi de l'ajout du mot "${selectedWord}" dans les lexiques :`, lexiconsToAdd);
+    const result = await window.AddWord(authToken, selectedWord, lexiconsToAdd, false);
+    
+    console.log("✅ Réponse API :", result);
 
-  // 6) Afficher un message récapitulatif
-  if (lexiconResultElement) {
-    let message = "";
-    const successful = addResults.filter(r => r.success).map(r => r.lexId);
-    const failed = addResults.filter(r => !r.success).map(r => r.lexId);
+    // Rafraîchir l'UI et la liste des entrées
+    await new Promise(resolve => setTimeout(resolve, 300));
+    browser.runtime.sendMessage({ action: "refreshUI" });
 
-    if (successful.length > 0) {
-      message += "✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans les lexiques : " + successful.join(", ") + ".";
+    // 7) Affichage du message de succès
+    if (lexiconResultElement) {
+      lexiconResultElement.innerHTML +=
+        "<br>✅ Mot <strong>" + selectedWord + "</strong> ajouté avec succès dans : " +
+        lexiconsToAdd.join(", ") + ".";
     }
-    if (failed.length > 0) {
-      message += "<br>❌ Échec de l'ajout dans les lexiques : " + failed.join(", ") + ".";
+
+  } catch (error) {
+    console.error("❌ Erreur lors de l’ajout du mot :", error);
+    if (lexiconResultElement) {
+      lexiconResultElement.textContent = "Erreur lors de l’ajout : " + error.message;
     }
-    lexiconResultElement.innerHTML = message;
   }
 }
 
 
+
+
+
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Réception des messages
 // ─────────────────────────────────────────────────────────────────────────────
diff --git a/definitions.js b/definitions.js
index 0e22bff..c8832d8 100644
--- a/definitions.js
+++ b/definitions.js
@@ -81,6 +81,7 @@ async function fetchLexiconDefinitions(word) {
     // 3) Parcourir les résultats et extraire les définitions
     let allDefinitions = [];
     results.forEach(result => {
+      console.log(`Pour le lexique ${result.lexiconId}, entrées filtrées :`, result.entries);
       const lexiconId = result.lexiconId;
       const sourceName = lexiconMap.get(lexiconId) || `Lexique #${lexiconId}`;
 
-- 
GitLab


From 6291ea0ef5ea70e26db10dc2a32df86cf9e38c88 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 19:04:22 +0100
Subject: [PATCH 05/23] Style bouton de connexion

---
 "barre_lat\303\251rale/sidebar.html" | 55 +++++++++++++++++++++++++---
 "barre_lat\303\251rale/sidebar.js"   |  1 +
 2 files changed, 51 insertions(+), 5 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 5ea40ba..4f9fc73 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -41,6 +41,45 @@
       margin-bottom: 0;
     }
 
+    /* Bouton de connexion */
+    #auth-button {
+      width: auto;
+      display: inline-flex;
+      padding: 6px 12px; 
+      font-size: 18px;
+      font-family: Bradley Hand, cursive;
+      background: none;
+      border: none;
+      color: white;
+      align-items: center;
+      gap: 6px;
+      border-radius: 20px;
+      cursor: pointer;
+      transition: background 0.3s;
+    }
+
+    #auth-button:hover {
+      background: rgba(255, 255, 255, 0.2);
+    }
+
+    #auth-button svg {
+      width: 18px;
+      height: 18px;
+      fill: white;
+      transition: transform 0.3s ease-in-out;
+    }
+
+    #auth-button:hover svg {
+      transform: scale(1.1);
+    }
+
+    #auth-section {
+      display: flex;
+      justify-content: flex-end;
+      margin-bottom: 10px;
+    }
+
+
     /* Utilisation de la classe pour les boutons de bascule */
     .toggle-btn {
       position: absolute;
@@ -96,8 +135,9 @@
       display: flex;
       align-items: center;
       justify-content: space-between;
-      padding: 8px;
+      padding: 6px;
       margin-bottom: 5px;
+      margin-top: 2px;
       border-radius: 5px;
       background-color: #dcdde1;
       width: 100%;
@@ -242,6 +282,15 @@
   
 </head>
 <body>
+  <!-- Bouton de connexion -->
+  <div id="auth-section">
+    <button id="auth-button">
+      <span id="auth-icon">
+        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 2a1 1 0 0 1 1 1v2h2V3a1 1 0 0 1 2 0v2h2a2 2 0 0 1 2 2v3h-2V7h-2v3a1 1 0 1 1-2 0V7h-2v3a1 1 0 1 1-2 0V7H6v3H4V7a2 2 0 0 1 2-2h2V3a1 1 0 0 1 1-1Zm-6 10h16v4a2 2 0 0 1-2 2h-4v2h2a1 1 0 1 1 0 2H8a1 1 0 1 1 0-2h2v-2H6a2 2 0 0 1-2-2v-4Z"/></svg>
+      </span>
+      <span id="auth-text">Se connecter</span>
+    </button>
+  </div>
 
   <!-- Bloc 1 : Menu des lexiques -->
   <div id="menu">
@@ -250,11 +299,7 @@
       <button class="toggle-btn"></button>
     </div>
     <div id="menuContent" class="block-content">
-      <p id="highlight-note" style="display: none;">Cochez un/des lexique(s) pour activer le surlignage des mots sur la page.</p>
       <div id="lexiques">Chargement...</div>
-      <div id="auth-section">
-        <button id="auth-button">Se connecter</button>
-      </div>
     </div>
   </div>
   
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index c01621b..c6400d6 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -47,6 +47,7 @@ function updateAuthButton(isLoggedIn) {
   }
 }
 
+
 function toggleElementsVisibility(isLoggedIn) {
   const elementsToShowOrHide = [
     { id: "add-to-lexiques", shouldShow: isLoggedIn },
-- 
GitLab


From 478194b8bf3608a46e191c52e2a8fa07ba6bea95 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sat, 8 Feb 2025 19:35:38 +0100
Subject: [PATCH 06/23] =?UTF-8?q?Ajout=20ic=C3=B4ne=20pour=20surligner?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.html" |  61 +++++++++++++++++++++++++--
 "barre_lat\303\251rale/sidebar.js"   |  41 +++++++++++++++---
 icons/feutre.png                     | Bin 0 -> 992 bytes
 3 files changed, 91 insertions(+), 11 deletions(-)
 create mode 100644 icons/feutre.png

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 4f9fc73..61f46c8 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -151,6 +151,7 @@
       font-weight: bold;
       color: #323046;
       flex-grow: 1;
+      font-size: 15px;
       text-align: center;
     }
 
@@ -161,13 +162,65 @@
       margin-left: 10px;
     }
 
-    /* Texte explicatif */
-    #highlight-note {
-      font-size: small;
-      margin-bottom: 10px;
+    /* Surlignage */
+    .lexique-highlight-toggle {
+      background: none;
+      border: none;
+      cursor: pointer;
+      font-size: 16px;
+      padding: 2px;
+      transition: transform 0.2s ease-in-out;
+      width: 15%;
+      position: relative;
+    }
+
+    .feutre-icon {
+      width: 20px;
+      height: 20px;
+      filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg); /* Gris par défaut */
+      transition: filter 0.3s ease-in-out;
+    }
+
+    .lexique-highlight-toggle[data-active="true"] .feutre-icon {
+      filter: brightness(0) saturate(100%) invert(83%) sepia(89%) saturate(588%) hue-rotate(360deg); /* Jaune */
+    }
+
+    .lexique-highlight-toggle:hover {
+      transform: scale(1.1);
+    }
+
+    /* Tooltip */
+    .tooltip {
+      position: absolute;
+      bottom: 120%;
+      transform: translateX(-50%);
+      background-color: rgba(0, 0, 0, 0.75);
+      color: #fff;
+      font-size: 12px;
+      padding: 6px 10px;
+      border-radius: 5px;
+      white-space: normal;
+      width: 150px; 
       text-align: center;
+      opacity: 0;
+      transition: opacity 0.3s ease-in-out;
+      pointer-events: none;
     }
 
+    /* Si l'icône est proche du bord gauche, décalage du tooltip vers la droite */
+    .lexique-highlight-toggle.left .tooltip {
+      left: 0;
+      transform: translateX(0);
+    }
+
+    /* Si l'icône est proche du bord droit, décalage du tooltip vers la gauche */
+    .lexique-highlight-toggle.right .tooltip {
+      right: 0;
+      left: auto;
+      transform: translateX(0);
+    }
+
+
     /* Espace pour les pictogrammes */
     .lexique-icon {
       width: 25px;
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index c6400d6..fbe771d 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -228,21 +228,27 @@ function displayLexiconsWithCheckbox(lexicons) {
     const addCheckbox = document.createElement("input");
     addCheckbox.type = "checkbox";
     addCheckbox.className = "lexique-add-checkbox";
-    // On stocke l'ID du lexique dans le dataset pour l'utiliser lors de l'ajout
     addCheckbox.dataset.lexiconId = lexiconId;
 
     // Le bouton pour activer/désactiver le surlignage
     const highlightButton = document.createElement("button");
     highlightButton.className = "lexique-highlight-toggle";
     highlightButton.dataset.lexiconId = lexiconId;
-    // Stocke l'état initial dans le dataset ("true" si actif, sinon "false")
     highlightButton.dataset.active = active ? "true" : "false";
-    // Définition du texte du bouton en fonction de l'état initial
-    highlightButton.textContent = active ? "Désactiver surlignage" : "Activer surlignage";
+
+    const feutreIcon = document.createElement("img");
+    feutreIcon.src = "/icons/feutre.png"; // Chemin de ton fichier SVG
+    feutreIcon.alt = "Feutre";
+    feutreIcon.className = "feutre-icon";
+
+    const tooltip = document.createElement("span");
+    tooltip.className = "tooltip";
+    tooltip.textContent = "Activer/Désactiver le surlignage des mots du lexique";
+
+    highlightButton.appendChild(feutreIcon);
 
     // Gestion du clic sur le bouton de surlignage
     highlightButton.addEventListener("click", async () => {
-      // On récupère l'état courant depuis le dataset
       let currentState = highlightButton.dataset.active === "true";
       let newState = !currentState;
       try {
@@ -252,24 +258,45 @@ function displayLexiconsWithCheckbox(lexicons) {
           lexiconId,
           isActive: newState,
         });
-        // Mise à jour de l'état stocké et du texte du bouton
+
+        // Mise à jour de l'état et du bouton
         highlightButton.dataset.active = newState ? "true" : "false";
-        highlightButton.textContent = newState ? "Désactiver surlignage" : "Activer surlignage";
       } catch (error) {
         console.error("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
       }
     });
 
+    highlightButton.addEventListener("mouseover", () => {
+      tooltip.style.opacity = "1";
+    });
+    highlightButton.addEventListener("mouseleave", () => {
+      tooltip.style.opacity = "0";
+    });
+
     // Assemblage de l'élément du lexique
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
     lexiqueDiv.appendChild(addCheckbox);
+    highlightButton.appendChild(tooltip);
     lexiqueDiv.appendChild(highlightButton);
     lexiquesContainer.appendChild(lexiqueDiv);
+    
+    // Vérification de la position pour éviter la coupure du tooltip
+    setTimeout(() => {
+      const rect = highlightButton.getBoundingClientRect();
+      const screenWidth = window.innerWidth;
+
+      if (rect.left < 100) {
+        highlightButton.classList.add("left");
+      } else if (rect.right > screenWidth - 100) {
+        highlightButton.classList.add("right");
+      }
+    }, 100);
   });
 }
 
 
+
 function initModal() {
   console.log("initModal appelé");
   const modalOverlay = document.getElementById("modalOverlay");
diff --git a/icons/feutre.png b/icons/feutre.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac98bf24c087760a7df319769db987664e72c3a6
GIT binary patch
literal 992
zcmV<610Vc}P)<h;3K|Lk000e1NJLTq001%o001%w1^@s69zTe&00009a7bBm000XU
z000XU0RWnu7ytkRl1W5CRCt{2nQ4fPQ5eU6w!si#tRb>QSt4up62%u=6tX4xpiEOF
zpDf82U+~GU>`^EtjEG4nWNXGGQ?iXU8Af9pJ@tR<xXp6!yWKnGUvKx`?m5qM{_lCt
zbDr}*@E@^YAaESW2WC=FF%|d%R5{N&>KRr6zcl!LKpya0zjLVvXaH=`fdA;bhougg
zjGmdMz%dQ95?EMGn~W#Z4k*+BKLHbKX`8WRdI2RGSSipyi9Q)eW-RbQ1G)`#Orh^G
zhs+Yvh<U(w4dgVC?Zd`$^?ym4uufUY2C*Gz<kQXs*?3FLXbkL<a|?^r0c`bk!g4(^
zq9t%njxD6-2F!9LvUL(@NKEJq+?8W{i(>-VY6jeJ5`>?%<qHFV=W_fM=o4_~KO$St
zfDXij$-rkhwzrrQ(B3v@R&9;M0?X|`oH(|S2!a*P`U(=7z6w7ty#`&3(}15!*$apP
zS->F?urhpQ2sVcT<+8b!7|;f|Du?EHdI&bV0xx894>6!8P$Y-1fFU8+Yy~`&&3tX9
zkzzPdCWq#@dk8k000px72xv{jm;ro~!-9|;HUJJf#b7rg#%kwWy<cxJ3~ZE56CMVW
zrgL>r%$H5uf2I&2Y*RbooU6mk>2|!Wl<hFmc8##p+bucz2#gQ89`j0>%|wV!K(R9u
z<~S^Laf-^r3f;(N;&FoFcPgaCovl*bY+jQj6gi0^)jS_VB4fwfGqP2z${=zQ_ni`a
zXh>vs%Eo)3HxZ&xj_&Db>0+d_I8XX0AJ(X^ZKflL_<UU@)vs+0ZTym%E8*d{Duc+&
z@p3t9UrW1G$&7KdtRM<XO7Ij9+ieMfOdqWW@30jca^-Yy5^d`ulOy4wN}0;9Am>{+
zFvpjYY+qA0bLE>mKnr5VXgR-`LZ8H$$<n8%w5K9chlV^2V0ViBTr#Cj_DklvAavNi
z@mg7Hn2-KOroySsYP-0J49y%7A=TM%)pk!wsVnP6M&g1~93J(NVO$c`-2+CB=D<Y_
zqRi2f4kwW50nE}Ri(TRma{l*7SV%5P7l{H5;tkMG*J3Ui+m){;l=I$WY4?glVsSc1
zWCNEINO*9`c#mBVYy~zc^gIF0Ti9tKVL0yy3A6bZrrDm={}r{wyoK8&og~wSCkb!d
za{msg82cOvbQ~FumcSg~0PwDw`2VU)$9jc^z$jn~@IZ^$Lgqh+34Z}-bU0uhh%Gq)
O0000<MNUMnLSTX*lDmTd

literal 0
HcmV?d00001

-- 
GitLab


From 177e7108f042f036510749cd575925a47fd9d20b Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:28:12 +0100
Subject: [PATCH 07/23] =?UTF-8?q?Tooltips=20ic=C3=B4nes=20ajout+surlignage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.html" | 220 ++++++++++++++-------------
 "barre_lat\303\251rale/sidebar.js"   |  81 +++++-----
 2 files changed, 158 insertions(+), 143 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 61f46c8..54335af 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -25,16 +25,16 @@
       margin-bottom: 10px;
       border-radius: 10px;
       background-color: #a08e9f;
-      box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
+      box-shadow: 0 2px 5px rgba(0,0,0,0.2);
+      overflow: visible;
     }
 
     /* En-têtes de blocs */
     .block-header {
       position: relative;
-      text-align: center; 
+      text-align: center;
       margin-top: 2px;
     }
-
     .block-header h3 {
       display: inline-block;
       margin-top: 5px;
@@ -45,7 +45,7 @@
     #auth-button {
       width: auto;
       display: inline-flex;
-      padding: 6px 12px; 
+      padding: 6px 12px;
       font-size: 18px;
       font-family: Bradley Hand, cursive;
       background: none;
@@ -57,30 +57,25 @@
       cursor: pointer;
       transition: background 0.3s;
     }
-
     #auth-button:hover {
-      background: rgba(255, 255, 255, 0.2);
+      background: rgba(255,255,255,0.2);
     }
-
     #auth-button svg {
       width: 18px;
       height: 18px;
       fill: white;
       transition: transform 0.3s ease-in-out;
     }
-
     #auth-button:hover svg {
       transform: scale(1.1);
     }
-
     #auth-section {
       display: flex;
       justify-content: flex-end;
       margin-bottom: 10px;
     }
 
-
-    /* Utilisation de la classe pour les boutons de bascule */
+    /* Boutons de bascule (toggle) */
     .toggle-btn {
       position: absolute;
       right: 8px;
@@ -88,23 +83,22 @@
       margin: 0;
       border: none;
       color: #fff;
-      font-size: 15px;  
-      padding: 3px 5px;  
+      font-size: 15px;
+      padding: 3px 5px;
       cursor: pointer;
-      width: auto;       
-      display: inline-block; 
+      width: auto;
+      display: inline-block;
     }
 
     /* Contenu des blocs */
     .block-content {
       padding-top: 2px;
     }
-
     .hidden {
       display: none;
     }
 
-    /* Boutons */
+    /* Boutons standards */
     button {
       width: 100%;
       margin-top: 5px;
@@ -117,7 +111,6 @@
       text-align: center;
       border-radius: 5px;
     }
-
     button:hover {
       background-color: #dddedd;
       color: #8d5c70;
@@ -137,16 +130,13 @@
       justify-content: space-between;
       padding: 6px;
       margin-bottom: 5px;
-      margin-top: 2px;
       border-radius: 5px;
       background-color: #dcdde1;
-      width: 100%;
+      position: relative;
     }
-
     .lexique-item:hover {
       background-color: #c4c7ce;
     }
-
     .lexique-label {
       font-weight: bold;
       color: #323046;
@@ -155,86 +145,123 @@
       text-align: center;
     }
 
-    .lexique-checkbox {
-      transform: scale(1.2);
-      cursor: pointer;
+    /* Icône du lexique */
+    .lexique-icon {
+      width: 25px;
+      height: 25px;
+      border-radius: 50%;
+      background-color: #ccc;
+      margin-right: 10px;
       flex-shrink: 0;
-      margin-left: 10px;
     }
 
-    /* Surlignage */
-    .lexique-highlight-toggle {
-      background: none;
-      border: none;
-      cursor: pointer;
-      font-size: 16px;
-      padding: 2px;
-      transition: transform 0.2s ease-in-out;
-      width: 15%;
+    /* Conteneur pour tooltip (pour checkbox et surlignage) */
+    .tooltip-container {
       position: relative;
+      display: inline-block;
+      cursor: pointer;
+      overflow: visible;
     }
 
-    .feutre-icon {
-      width: 20px;
-      height: 20px;
-      filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg); /* Gris par défaut */
-      transition: filter 0.3s ease-in-out;
-    }
-
-    .lexique-highlight-toggle[data-active="true"] .feutre-icon {
-      filter: brightness(0) saturate(100%) invert(83%) sepia(89%) saturate(588%) hue-rotate(360deg); /* Jaune */
-    }
-
-    .lexique-highlight-toggle:hover {
-      transform: scale(1.1);
-    }
-
-    /* Tooltip */
+    /* Style uniformisé pour tous les tooltips */
     .tooltip {
+      all: unset;
+      display: block;
+      box-sizing: border-box;
       position: absolute;
       bottom: 120%;
+      left: 50%;
       transform: translateX(-50%);
-      background-color: rgba(0, 0, 0, 0.75);
+      background-color: rgba(0,0,0,0.75);
       color: #fff;
-      font-size: 12px;
+      font-size: 12px !important;
+      font-weight: lighter !important;
       padding: 6px 10px;
       border-radius: 5px;
-      white-space: normal;
-      width: 150px; 
+      white-space: normal;            
+      overflow-wrap: break-word;     
+      width: 180px;
       text-align: center;
       opacity: 0;
-      transition: opacity 0.3s ease-in-out;
+      transition: opacity 0.3s ease-in-out, transform 0.2s ease-in-out;
       pointer-events: none;
+      z-index: 10;
+      line-height: normal;
     }
 
-    /* Si l'icône est proche du bord gauche, décalage du tooltip vers la droite */
-    .lexique-highlight-toggle.left .tooltip {
+    .tooltip-container:hover .tooltip {
+      opacity: 1;
+      transform: translateX(-50%) translateY(-5px);
+    }
+    /* Positionnement ajusté si le conteneur est trop proche des bords */
+    .tooltip-container.left .tooltip {
       left: 0;
-      transform: translateX(0);
+      transform: translateX(0) translateY(-5px);
     }
-
-    /* Si l'icône est proche du bord droit, décalage du tooltip vers la gauche */
-    .lexique-highlight-toggle.right .tooltip {
+    .tooltip-container.right .tooltip {
       right: 0;
       left: auto;
-      transform: translateX(0);
+      transform: translateX(0) translateY(-5px);
     }
 
+    /* Cases à cocher personnalisées */
+    .lexique-checkbox {
+      appearance: none;
+      width: 20px;
+      height: 20px;
+      border: 2px solid #8d5c70;
+      border-radius: 5px;
+      background-color: #fff;
+      transition: background 0.3s ease, border-color 0.3s ease;
+      cursor: pointer;
+      position: relative;
+    }
+    .lexique-checkbox:hover {
+      border-color: #6a3e50;
+    }
+    .lexique-checkbox:checked {
+      background-color: #8d5c70;
+      border-color: #8d5c70;
+    }
+    .lexique-checkbox:checked::after {
+      content: '✔';
+      font-size: 16px;
+      color: white;
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+    }
 
-    /* Espace pour les pictogrammes */
-    .lexique-icon {
-      width: 25px;
-      height: 25px;
-      border-radius: 50%;
-      background-color: #ccc;
-      margin-right: 10px;
-      flex-shrink: 0;
+    /* Bouton de surlignage */
+    .lexique-highlight-toggle {
+      background: none;
+      border: none;
+      cursor: pointer;
+      font-size: 16px;
+      padding: 2px;
+      transition: transform 0.2s ease-in-out;
+      width: 15%;
+      position: relative;
+    }
+    
+    .feutre-icon {
+      width: 20px;
+      height: 20px;
+      filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg);
+      transition: filter 0.3s ease-in-out;
+    }
+    .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:hover {
+      transform: scale(1.1);
     }
 
+    /* Autres styles divers */
     .lexicon-section {
       margin-bottom: 10px;
     }
-
     .lexicon-header {
       font-weight: bold;
       cursor: pointer;
@@ -243,72 +270,59 @@
       border-radius: 5px;
       text-align: center;
     }
-
     .lexicon-header:hover {
       background-color: #dddedd;
       color: #8d5c70;
     }
-
     .lexicon-content {
       margin-top: 5px;
     }
-
     #mesLexiquesList {
       display: inline;
       padding: 0;
       align-items: center;
     }
-
     #mesLexiquesContainer h4 {
       margin-bottom: 5px;
     }
-
-    /* Définition */
     #definitionContainer {
       background-color: #444;
       padding: 10px;
       border-radius: 10px;
       color: white;
     }
-
     #definitionsList {
       list-style: none;
       padding: 0;
     }
-    
     #definitionsList li {
       margin-bottom: 10px;
     }
-
     .definition-source {
       font-weight: bold;
       color: #ffa500;
     }
-
-    /* Popup (modal) caché par défaut */
     .modal-overlay {
       position: fixed;
-      top: 0; 
-      left: 0; 
-      width: 100vw; 
-      height: 100vh; 
-      background: rgba(0,0,0,0.5); 
-      display: none; 
-      align-items: center; 
-      justify-content: center; 
-      z-index: 9999; 
+      top: 0;
+      left: 0;
+      width: 100vw;
+      height: 100vh;
+      background: rgba(0,0,0,0.5);
+      display: none;
+      align-items: center;
+      justify-content: center;
+      z-index: 9999;
     }
-
     .modal-content {
-      background: white; 
+      background: white;
       color: #8d5c70;
-      padding: 1rem; 
-      max-width: 600px; 
+      padding: 1rem;
+      max-width: 600px;
       max-height: 80vh;
       overflow-y: auto;
       border-radius: 8px;
     }
-
     .close-button {
       float: right;
       cursor: pointer;
@@ -318,28 +332,26 @@
     .close-button:hover {
       color: #000;
     }
-
-    /* Activer/désactiver le surlignage */
     #highlighting-options p {
       margin: 5px 0;
       font-size: small;
       color: #333;
     }
-
     #noDefinitionsContainer {
       display: block !important;
       color: red !important;
       font-weight: bold;
     }
   </style>
-  
 </head>
 <body>
   <!-- Bouton de connexion -->
   <div id="auth-section">
     <button id="auth-button">
       <span id="auth-icon">
-        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 2a1 1 0 0 1 1 1v2h2V3a1 1 0 0 1 2 0v2h2a2 2 0 0 1 2 2v3h-2V7h-2v3a1 1 0 1 1-2 0V7h-2v3a1 1 0 1 1-2 0V7H6v3H4V7a2 2 0 0 1 2-2h2V3a1 1 0 0 1 1-1Zm-6 10h16v4a2 2 0 0 1-2 2h-4v2h2a1 1 0 1 1 0 2H8a1 1 0 1 1 0-2h2v-2H6a2 2 0 0 1-2-2v-4Z"/></svg>
+        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+          <path d="M10 2a1 1 0 0 1 1 1v2h2V3a1 1 0 0 1 2 0v2h2a2 2 0 0 1 2 2v3h-2V7h-2v3a1 1 0 1 1-2 0V7h-2v3a1 1 0 1 1-2 0V7H6v3H4V7a2 2 0 0 1 2-2h2V3a1 1 0 0 1 1-1Z"/>
+        </svg>
       </span>
       <span id="auth-text">Se connecter</span>
     </button>
@@ -355,7 +367,7 @@
       <div id="lexiques">Chargement...</div>
     </div>
   </div>
-  
+
   <!-- Bloc 2 : État de la sélection -->
   <div id="etat">
     <div class="block-header">
@@ -372,7 +384,7 @@
       <div id="possible-definitions" style="display: none;"></div>
     </div>
   </div>
-  
+
   <!-- Bloc 3 : Définitions -->
   <div id="definitionContainer">
     <div class="block-header">
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index fbe771d..cca0470 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -210,93 +210,96 @@ function displayLexiconsWithCheckbox(lexicons) {
   }
 
   lexicons.forEach(({ lexiconName, lexiconId, active }) => {
-    // Création du conteneur pour ce lexique
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
 
-    // Optionnel : un élément visuel (icône)
+    // Icône du lexique
     const iconDiv = document.createElement("div");
     iconDiv.className = "lexique-icon";
-    iconDiv.style.backgroundColor = "#ccc";
 
-    // Le label affichant le nom du lexique
     const labelSpan = document.createElement("span");
     labelSpan.className = "lexique-label";
     labelSpan.textContent = lexiconName;
 
-    // La case à cocher servant à sélectionner le lexique pour l'ajout d'un mot
+    // Conteneur pour la case à cocher avec tooltip
+    const checkboxContainer = document.createElement("label");
+    checkboxContainer.className = "tooltip-container lexique-checkbox-container";
+
     const addCheckbox = document.createElement("input");
     addCheckbox.type = "checkbox";
-    addCheckbox.className = "lexique-add-checkbox";
+    addCheckbox.className = "lexique-checkbox";
     addCheckbox.dataset.lexiconId = lexiconId;
 
-    // Le bouton pour activer/désactiver le surlignage
+    const checkboxTooltip = document.createElement("span");
+    checkboxTooltip.className = "tooltip";
+    checkboxTooltip.textContent = "Ajouter le mot à ce lexique";
+
+    // Conteneur pour le bouton de surlignage avec tooltip
     const highlightButton = document.createElement("button");
-    highlightButton.className = "lexique-highlight-toggle";
+    highlightButton.className = "tooltip-container lexique-highlight-toggle";
     highlightButton.dataset.lexiconId = lexiconId;
     highlightButton.dataset.active = active ? "true" : "false";
 
     const feutreIcon = document.createElement("img");
-    feutreIcon.src = "/icons/feutre.png"; // Chemin de ton fichier SVG
+    feutreIcon.src = "/icons/feutre.png";
     feutreIcon.alt = "Feutre";
     feutreIcon.className = "feutre-icon";
 
-    const tooltip = document.createElement("span");
-    tooltip.className = "tooltip";
-    tooltip.textContent = "Activer/Désactiver le surlignage des mots du lexique";
-
-    highlightButton.appendChild(feutreIcon);
+    const highlightTooltip = document.createElement("span");
+    highlightTooltip.className = "tooltip";
+    highlightTooltip.textContent = "Activer/Désactiver le surlignage des mots du lexique";
 
-    // Gestion du clic sur le bouton de surlignage
+    // Gestion du clic pour activer/désactiver le surlignage
     highlightButton.addEventListener("click", async () => {
       let currentState = highlightButton.dataset.active === "true";
       let newState = !currentState;
       try {
-        // Envoi d'un message pour demander au background de changer l'état de surlignage
         await browser.runtime.sendMessage({
           action: "toggleLexiconHighlight",
           lexiconId,
           isActive: newState,
         });
-
-        // Mise à jour de l'état et du bouton
         highlightButton.dataset.active = newState ? "true" : "false";
       } catch (error) {
         console.error("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
       }
     });
 
-    highlightButton.addEventListener("mouseover", () => {
-      tooltip.style.opacity = "1";
-    });
-    highlightButton.addEventListener("mouseleave", () => {
-      tooltip.style.opacity = "0";
-    });
+    // Assemblage
+    highlightButton.appendChild(feutreIcon);
+    highlightButton.appendChild(highlightTooltip);
+    checkboxContainer.appendChild(addCheckbox);
+    checkboxContainer.appendChild(checkboxTooltip);
 
-    // Assemblage de l'élément du lexique
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
-    lexiqueDiv.appendChild(addCheckbox);
-    highlightButton.appendChild(tooltip);
+    lexiqueDiv.appendChild(checkboxContainer);
     lexiqueDiv.appendChild(highlightButton);
     lexiquesContainer.appendChild(lexiqueDiv);
-    
-    // Vérification de la position pour éviter la coupure du tooltip
-    setTimeout(() => {
-      const rect = highlightButton.getBoundingClientRect();
-      const screenWidth = window.innerWidth;
-
-      if (rect.left < 100) {
-        highlightButton.classList.add("left");
-      } else if (rect.right > screenWidth - 100) {
-        highlightButton.classList.add("right");
-      }
-    }, 100);
   });
+
+  // Ajustement dynamique des tooltips pour éviter qu'ils ne soient coupés
+  setTimeout(() => {
+    const containers = document.querySelectorAll('.tooltip-container');
+    const menuRect = document.getElementById("menu").getBoundingClientRect();
+    containers.forEach(container => {
+      container.classList.remove('left', 'right');
+      const rect = container.getBoundingClientRect();
+      // Si le conteneur est trop proche du bord gauche du menu
+      if (rect.left < menuRect.left + 50) {
+        container.classList.add("left");
+      }
+      // Si le conteneur est trop proche du bord droit du menu
+      else if (rect.right > menuRect.right - 50) {
+        container.classList.add("right");
+      }
+    });
+  }, 100);
 }
 
 
 
+
 function initModal() {
   console.log("initModal appelé");
   const modalOverlay = document.getElementById("modalOverlay");
-- 
GitLab


From f66780c18ae8abfc8e7e53f294d67a08161de185 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sun, 9 Feb 2025 14:59:42 +0100
Subject: [PATCH 08/23] Fermeture des blocs ouverture extension

---
 "barre_lat\303\251rale/sidebar.html" |  8 +++----
 "barre_lat\303\251rale/sidebar.js"   | 35 ++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 4 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 54335af..40e9ed6 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -361,9 +361,9 @@
   <div id="menu">
     <div class="block-header">
       <h3>Lexiques</h3>
-      <button class="toggle-btn"></button>
+      <button class="toggle-btn">+</button>
     </div>
-    <div id="menuContent" class="block-content">
+    <div id="menuContent" class="block-content hidden">
       <div id="lexiques">Chargement...</div>
     </div>
   </div>
@@ -374,7 +374,7 @@
       <h3>Mot sélectionné</h3>
       <button class="toggle-btn"></button>
     </div>
-    <div id="etatContent" class="block-content">
+    <div id="etatContent" class="block-content hidden">
       <p id="motSelectionne">Aucun mot sélectionné</p>
       <p id="lexiconResult"></p>
       <div id="add-to-lexiques" style="display: none;">
@@ -391,7 +391,7 @@
       <h3>Définitions</h3>
       <button class="toggle-btn"></button>
     </div>
-    <div id="definitionContent" class="block-content">
+    <div id="definitionContent" class="block-content hidden">
       <!-- Définitions des lexiques de l'utilisateur -->
       <div id="mesLexiquesContainer">
         <h4>📚 Mes lexiques</h4>
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index cca0470..2bf8125 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -571,5 +571,40 @@ document.addEventListener("DOMContentLoaded", async () => {
         btn.textContent = content.classList.contains("hidden") ? "+" : "–";
       }
     });
+
+    document.querySelectorAll('.block-content').forEach(block => {
+      block.classList.add('hidden');
+    });
+  
+    document.querySelectorAll('.toggle-btn').forEach(btn => {
+      // Forcer l'affichage initial à "+"
+      btn.textContent = '+';
+      btn.style.fontSize = '15px';
+  
+      // Gestion du clic sur le bouton
+      btn.addEventListener('click', (event) => {
+        event.stopPropagation();
+        const header = btn.parentElement;
+        const content = header.nextElementSibling;
+        if (content) {
+          content.classList.toggle('hidden');
+          // Mettre à jour le texte du bouton selon l'état du bloc
+          btn.textContent = content.classList.contains('hidden') ? '+' : '–';
+        }
+      });
+    });
+  });
+});
+
+document.querySelectorAll('.toggle-btn').forEach(btn => {
+  btn.addEventListener('click', function() {
+    const blockContent = this.parentElement.nextElementSibling;
+    if (blockContent.classList.contains('hidden')) {
+      blockContent.classList.remove('hidden');
+      this.textContent = '–'; // affiche le symbole pour fermer
+    } else {
+      blockContent.classList.add('hidden');
+      this.textContent = '+'; // affiche le symbole pour ouvrir
+    }
   });
 });
-- 
GitLab


From cd6332be8763092f1b900f8db7ad71df5a46d65d Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sun, 9 Feb 2025 17:13:32 +0100
Subject: [PATCH 09/23] Correction affichage tooltips

---
 "barre_lat\303\251rale/sidebar.html" | 40 +++++++++++++++++++++++++---
 "barre_lat\303\251rale/sidebar.js"   | 29 ++++++++++++--------
 2 files changed, 54 insertions(+), 15 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 40e9ed6..28f7552 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -174,7 +174,7 @@
       transform: translateX(-50%);
       background-color: rgba(0,0,0,0.75);
       color: #fff;
-      font-size: 12px !important;
+      font-size: 14px !important;
       font-weight: lighter !important;
       padding: 6px 10px;
       border-radius: 5px;
@@ -238,7 +238,6 @@
       background: none;
       border: none;
       cursor: pointer;
-      font-size: 16px;
       padding: 2px;
       transition: transform 0.2s ease-in-out;
       width: 15%;
@@ -251,13 +250,46 @@
       filter: brightness(0) saturate(100%) invert(40%) sepia(0%) saturate(0%) hue-rotate(0deg);
       transition: filter 0.3s ease-in-out;
     }
+
     .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:hover {
-      transform: scale(1.1);
+
+    /* Cibler les tooltips à l'intérieur d'un bouton de surlignage */
+    button.lexique-highlight-toggle .tooltip {
+      /* Réinitialiser toute influence du style global du bouton */
+      all: unset;
+      /* Appliquer les styles désirés pour le tooltip */
+      display: block;
+      box-sizing: border-box;
+      position: absolute;
+      bottom: 120%;
+      left: 50%;
+      transform: translateX(-50%) translateY(-5px);
+      background-color: rgba(0, 0, 0, 0.75);
+      color: #fff;
+      font-size: 14px;
+      font-weight: lighter;
+      padding: 6px 10px;
+      border-radius: 5px;
+      white-space: normal;
+      overflow-wrap: break-word;
+      width: 180px;
+      text-align: center;
+      opacity: 0;
+      transition: opacity 0.3s ease-in-out, transform 0.2s ease-in-out;
+      pointer-events: none;
+      z-index: 10;
+      line-height: normal;
+    }
+
+    /* Lors du survol du conteneur, afficher le tooltip */
+    button.lexique-highlight-toggle:hover .tooltip {
+      opacity: 1;
+      transform: translateX(-50%) translateY(-5px);
     }
 
+
     /* Autres styles divers */
     .lexicon-section {
       margin-bottom: 10px;
diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 2bf8125..0ec7390 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -278,24 +278,31 @@ function displayLexiconsWithCheckbox(lexicons) {
     lexiquesContainer.appendChild(lexiqueDiv);
   });
 
-  // Ajustement dynamique des tooltips pour éviter qu'ils ne soient coupés
+  // Ajustement dynamique des tooltips
   setTimeout(() => {
+    const menu = document.getElementById("menu");
+    const menuRect = menu.getBoundingClientRect();
     const containers = document.querySelectorAll('.tooltip-container');
-    const menuRect = document.getElementById("menu").getBoundingClientRect();
+  
     containers.forEach(container => {
-      container.classList.remove('left', 'right');
-      const rect = container.getBoundingClientRect();
-      // Si le conteneur est trop proche du bord gauche du menu
-      if (rect.left < menuRect.left + 50) {
-        container.classList.add("left");
+      const tooltip = container.querySelector('.tooltip');
+      if (!tooltip) return;
+
+      tooltip.style.left = '50%';
+      tooltip.style.transform = 'translateX(-50%) translateY(-5px)';
+  
+      const tooltipRect = tooltip.getBoundingClientRect();
+      if (tooltipRect.left < menuRect.left) {
+        const overflowLeft = menuRect.left - tooltipRect.left;
+        tooltip.style.transform = `translateX(calc(-100% + ${overflowLeft}px)) translateY(-5px)`;
       }
-      // Si le conteneur est trop proche du bord droit du menu
-      else if (rect.right > menuRect.right - 50) {
-        container.classList.add("right");
+      else if (tooltipRect.right > menuRect.right) {
+        const overflowRight = tooltipRect.right - menuRect.right;
+        tooltip.style.transform = `translateX(calc(-100% - ${overflowRight}px)) translateY(-5px)`;
       }
     });
   }, 100);
-}
+}  
 
 
 
-- 
GitLab


From ed17ad8f12fa2358df09191b7460d6c17e0502f7 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sun, 9 Feb 2025 17:22:12 +0100
Subject: [PATCH 10/23] Correction ouverture automatique bloc Lexiques

---
 "barre_lat\303\251rale/sidebar.js" | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 0ec7390..33bf220 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -348,6 +348,7 @@ async function handleAuthButtonClick() {
  * et les lexiques cochés, puis on appelle AddWord.
  */
 async function handleAddWordClick() {
+  openBlock("menuContent");
   // 1) Vérifier la présence du token et du mot
   if (!authToken) {
     console.warn("⚠️ Pas de token d'authentification : impossible d'ajouter le mot.");
@@ -554,7 +555,7 @@ document.addEventListener("DOMContentLoaded", async () => {
     });
   }
 
-  // Bouton "Ajouter au(x) lexique(s)"
+  // Bouton "Ajouter le mot sélectionné"
   const addWordButton = document.getElementById("add-word-button");
   if (addWordButton) {
     addWordButton.addEventListener("click", handleAddWordClick);
-- 
GitLab


From 6ef851cfa48b212ff7fd3c9485d85e70b51d4315 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Sun, 9 Feb 2025 17:26:54 +0100
Subject: [PATCH 11/23] =?UTF-8?q?Fermeture=20automatiquement=20blocs=20d?=
 =?UTF-8?q?=C3=A9connexion?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.js" | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 33bf220..289ed8c 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -88,6 +88,19 @@ async function refreshSidebarState() {
   if (isLoggedIn) {
     await fetchLexicons();
   } else {
+    // Si l'utilisateur n'est pas connecté, on ferme tous les blocs
+    document.querySelectorAll('.block-content').forEach(block => {
+      block.classList.add('hidden');
+      // Mise à jour des boutons de bascule associés pour afficher le symbole "+"
+      const header = block.previousElementSibling;
+      if (header) {
+        const toggleBtn = header.querySelector(".toggle-btn");
+        if (toggleBtn) {
+          toggleBtn.textContent = '+';
+        }
+      }
+    });
+    
     const lexiquesContainer = document.getElementById("lexiques");
     if (lexiquesContainer) {
       lexiquesContainer.textContent = "Veuillez vous connecter pour voir vos lexiques.";
-- 
GitLab


From 5893ca872d2d3387ae9946218a937c1a4ef84314 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Mon, 10 Feb 2025 13:05:04 +0100
Subject: [PATCH 12/23] =?UTF-8?q?Affichage=20automatique=20d=C3=A9finition?=
 =?UTF-8?q?s=20menu=20navigateur?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.js"      |  56 +++++--
 manifest.json                           |   5 +-
 menu_contextuel/browser_context_menu.js | 207 +++++++++++++++++-------
 3 files changed, 194 insertions(+), 74 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index 289ed8c..a6ac96e 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -382,8 +382,8 @@ async function handleAddWordClick() {
     return;
   }
 
-  // 2) Récupérer les IDs des lexiques sélectionnés (cases à cocher “add-checkbox”)
-  const checkboxList = document.querySelectorAll("#lexiques .lexique-add-checkbox:checked");
+  // 2) Récupérer les IDs des lexiques sélectionnés
+  const checkboxList = document.querySelectorAll("#lexiques .lexique-checkbox:checked");
   const selectedLexiconIds = Array.from(checkboxList).map(cb => parseInt(cb.dataset.lexiconId, 10));
 
   if (selectedLexiconIds.length === 0) {
@@ -465,22 +465,22 @@ browser.runtime.onMessage.addListener(async (message) => {
       await refreshSidebarState();
       break;
 
-      case "mot_selectionne":
-        if (message.selectedText) {
-          console.log("🖋️ Mot sélectionné :", message.selectedText);
-          const selectedWordElement = document.getElementById("motSelectionne");
-          if (selectedWordElement) {
-            selectedWordElement.textContent = message.selectedText;
-          } else {
-            console.warn("⚠️ Élément #motSelectionne introuvable.");
-          }
-          const lexiconResultElement = document.getElementById("lexiconResult");
-          if (lexiconResultElement) {
-            lexiconResultElement.innerHTML = "";
-          }
-          openBlock("etatContent");
+    case "mot_selectionne":
+      if (message.selectedText) {
+        console.log("🖋️ Mot sélectionné :", message.selectedText);
+        const selectedWordElement = document.getElementById("motSelectionne");
+        if (selectedWordElement) {
+          selectedWordElement.textContent = message.selectedText;
+        } else {
+          console.warn("⚠️ Élément #motSelectionne introuvable.");
+        }
+        const lexiconResultElement = document.getElementById("lexiconResult");
+        if (lexiconResultElement) {
+          lexiconResultElement.innerHTML = "";
         }
-        break;
+        openBlock("etatContent");
+      }
+      break;
 
     case "getDefinition":
       if (message.selectedText) {
@@ -514,6 +514,28 @@ browser.runtime.onMessage.addListener(async (message) => {
     case "authStatusChanged":
       break;
 
+    case "wordAdded":
+      {
+        // Affichage du message de succès dans la sidebar
+        const lexiconResultElement = document.getElementById("lexiconResult");
+        if (lexiconResultElement) {
+          lexiconResultElement.innerHTML +=
+            "<br>✅ Mot <strong>" + message.selectedWord + "</strong> ajouté avec succès dans : " +
+            message.lexiconIds.join(", ") + ".";
+        }
+      }
+      break;
+      
+    case "wordAddFailed":
+      {
+        // Affichage du message d'erreur dans la sidebar
+        const lexiconResultElement = document.getElementById("lexiconResult");
+        if (lexiconResultElement) {
+          lexiconResultElement.textContent = "Erreur lors de l'ajout du mot : " + message.error;
+        }
+      }
+      break;
+
     default:
       console.warn("⚠️ Action inconnue reçue :", message.action);
   }
diff --git a/manifest.json b/manifest.json
index c2b94ca..b652cb0 100644
--- a/manifest.json
+++ b/manifest.json
@@ -22,8 +22,9 @@
     "scripts": [
       "background/background.js", 
       "definitions.js",
-      "menu_contextuel/browser_context_menu.js",
-      "api.js"],
+      "api.js",
+      "menu_contextuel/browser_context_menu.js"
+    ],
     "persistent": true
   },
 
diff --git a/menu_contextuel/browser_context_menu.js b/menu_contextuel/browser_context_menu.js
index a2ba1fa..8528524 100644
--- a/menu_contextuel/browser_context_menu.js
+++ b/menu_contextuel/browser_context_menu.js
@@ -1,6 +1,7 @@
 console.log("browser_context_menu.js chargé correctement");
 
 let authToken = null;
+let selectedLexicons = new Set();
 
 /**
  * Charge le token depuis le stockage local et le stocke dans la variable globale authToken.
@@ -15,9 +16,12 @@ async function loadAuthToken() {
   }
 }
 
-// ─────────────────────────────────────────────────────────────────────────────
-// Création du menu contextuel en fonction de l'authentification
-// ─────────────────────────────────────────────────────────────────────────────
+/**
+ * Crée le menu contextuel en fonction de l'authentification.
+ * Si l'utilisateur est connecté, on ajoute un item pour la recherche et
+ * un menu parent pour l'ajout du mot avec des cases à cocher pour chaque lexique
+ * et un item de confirmation.
+ */
 async function createContextMenu() {
   await browser.contextMenus.removeAll();
 
@@ -30,15 +34,58 @@ async function createContextMenu() {
       icons: { "16": "icons/quel_lexique.png" },
     });
 
-    // Item 2 : Ajouter un mot au lexique personnel
+    // Menu parent pour ajouter le mot dans les lexiques choisis
     browser.contextMenus.create({
-      id: "addtoLexicon",
-      title: "Ajouter ce mot à mon lexique",
+      id: "parentAddLexicon",
+      title: "Ajouter ce mot à…",
       contexts: ["selection"],
-      icons: { "16": "icons/ajout_lexique.png" },
+    });
+
+    // Récupérer dynamiquement les lexiques
+    let lexicons = [];
+    try {
+      lexicons = await window.getLexicons(authToken);
+    } catch (error) {
+      console.error("Erreur lors de la récupération des lexiques :", error);
+    }
+
+    if (Array.isArray(lexicons) && lexicons.length > 0) {
+      lexicons.forEach(lexicon => {
+        let title = "";
+        if (lexicon.category === "User") {
+          title = `Lexique personnel (${(lexicon.user && lexicon.user.pseudo) || "Inconnu"}) [${lexicon.id}]`;
+        } else {
+          title = `Lexique de groupe (${(lexicon.group && lexicon.group.name) || "Inconnu"}) [${lexicon.id}]`;
+        }
+        browser.contextMenus.create({
+          id: `addWord_${lexicon.id}`,
+          title: title,
+          type: "checkbox",
+          contexts: ["selection"],
+          parentId: "parentAddLexicon",
+          checked: false
+        });
+      });
+    } else {
+      browser.contextMenus.create({
+        id: "noLexiconsFound",
+        title: "Aucun lexique trouvé",
+        contexts: ["selection"],
+        parentId: "parentAddLexicon",
+        enabled: false
+      });
+    }
+
+    // Item de confirmation pour lancer l'ajout dans les lexiques sélectionnés
+    browser.contextMenus.create({
+      id: "confirmAddWord",
+      title: "Confirmer l'ajout",
+      contexts: ["selection"],
+      parentId: "parentAddLexicon",
     });
   }
 
+  // Séparateur
   browser.contextMenus.create({
     id: "separatorExtension",
     type: "separator",
@@ -59,6 +106,7 @@ async function createContextMenu() {
     contexts: ["all"],
   });
   
+  // Item de connexion/déconnexion
   browser.contextMenus.create({
     id: "login",
     title: authToken ? "Se déconnecter de BaLex" : "Se connecter à BaLex",
@@ -87,7 +135,8 @@ browser.storage.onChanged.addListener((changes, area) => {
 // ─────────────────────────────────────────────────────────────────────────────
 browser.contextMenus.onClicked.addListener(async (info, tab) => {
   console.log("Item de menu cliqué :", info.menuItemId);
-  
+
+  // Action pour le bouton de connexion/déconnexion
   if (info.menuItemId === "login") {
     console.log("🔄 Action login/déconnexion demandée.");
     if (typeof actuallyOpenLoginPage === "function") {
@@ -102,7 +151,8 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
     console.warn("Aucun texte sélectionné pour cette action :", info.menuItemId);
     return;
   }
-  console.log(`📩 Texte sélectionné : ${info.selectionText}`);
+  const selectedText = info.selectionText.trim();
+  console.log(`📩 Texte sélectionné : ${selectedText}`);
 
   switch (info.menuItemId) {
     case "searchInLexicons":
@@ -110,46 +160,122 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
         alert("⚠️ Vous devez être connecté pour utiliser cette fonction.");
         return;
       }
-      await searchInLexicons(info.selectionText);
+      await searchInLexicons(selectedText);
       break;
 
-    case "addtoLexicon":
+    case "confirmAddWord":
       if (!authToken) {
         alert("⚠️ Vous devez être connecté pour utiliser cette fonction.");
         return;
       }
-      await addWordToLexicon(info.selectionText);
+      if (!selectedText || selectedText === "Aucun mot sélectionné") {
+        console.warn("⚠️ Aucun mot à ajouter.");
+        browser.runtime.sendMessage({
+          action: "wordAddFailed",
+          error: "Aucun mot à ajouter."
+        });
+        return;
+      }
+      if (selectedLexicons.size === 0) {
+        alert("Veuillez sélectionner au moins un lexique.");
+        return;
+      }
+      {
+        // Vérifier si le mot existe déjà dans les lexiques sélectionnés
+        let definitions = [];
+        try {
+          definitions = await window.fetchLexiconDefinitions(selectedText);
+        } catch (error) {
+          console.error("Erreur lors de la récupération des définitions pour vérification :", error);
+        }
+        const existingLexiconIds = new Set();
+        if (Array.isArray(definitions)) {
+          for (const def of definitions) {
+            if (selectedLexicons.has(def.lexiconId)) {
+              existingLexiconIds.add(def.lexiconId);
+            }
+          }
+        }
+        if (existingLexiconIds.size > 0) {
+          alert(`Le mot "${selectedText}" existe déjà dans le(s) lexique(s) : ${Array.from(existingLexiconIds).join(", ")}`);
+          browser.runtime.sendMessage({
+            action: "wordAlreadyExists",
+            selectedWord: selectedText,
+            lexiconIds: Array.from(existingLexiconIds)
+          });
+          return;
+        }
+        // On détermine quels lexiques ajouter (ceux non existants)
+        const lexiconsToAdd = Array.from(selectedLexicons).filter(id => !existingLexiconIds.has(id));
+        if (lexiconsToAdd.length === 0) {
+          return; // Rien à ajouter
+        }
+        // Envoi de la requête d'ajout
+        try {
+          console.log(`📡 Envoi de l'ajout du mot "${selectedText}" dans le(s) lexique(s) :`, lexiconsToAdd);
+          const result = await window.AddWord(authToken, selectedText, lexiconsToAdd, false);
+          console.log("✅ Réponse API :", result);
+          await browser.runtime.sendMessage({ action: "refreshUI" });
+          browser.runtime.sendMessage({
+            action: "wordAdded",
+            selectedWord: selectedText,
+            lexiconIds: lexiconsToAdd,
+            result
+          });
+          // Réinitialiser la sélection après ajout
+          selectedLexicons.clear();
+        } catch (error) {
+          console.error("❌ Erreur lors de l’ajout du mot :", error);
+          alert("❌ Une erreur est survenue lors de l’ajout du mot : " + error.message);
+          browser.runtime.sendMessage({
+            action: "wordAddFailed",
+            selectedWord: selectedText,
+            lexiconIds: Array.from(selectedLexicons),
+            error: error.message
+          });
+        }
+      }
       break;
 
-    case "getDefinition":
-      await getDefinition(info.selectionText);
-      break;
-      
     default:
-      console.error(`❌ Action inconnue : ${info.menuItemId}`);
+      // Gérer les items de type "checkbox"
+      if (info.menuItemId.startsWith("addWord_")) {
+        const lexiconId = parseInt(info.menuItemId.replace("addWord_", ""), 10);
+        if (isNaN(lexiconId)) {
+          console.error("❌ ID de lexique invalide :", info.menuItemId);
+          return;
+        }
+        if (info.checked) {
+          selectedLexicons.add(lexiconId);
+        } else {
+          selectedLexicons.delete(lexiconId);
+        }
+        console.log("Lexicons sélectionnés :", Array.from(selectedLexicons));
+      } else if (info.menuItemId === "getDefinition") {
+        await browser.runtime.sendMessage({
+          action: "getDefinition",
+          selectedText: info.selectionText.trim(),
+        });
+        return;
+      } else {
+        console.error(`❌ Action inconnue : ${info.menuItemId}`);
+      }
+      break;
   }
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
-// Fonctions liées aux définitions (definitions.js)
+// Fonctions liées aux définitions
 // ─────────────────────────────────────────────────────────────────────────────
-
-/**
- * 1) Recherche de la définition combinée (lexiques + Wiktionnaire)
- *    et envoi des résultats pour affichage.
- */
 async function getDefinition(selectedText) {
   try {
     let lexiconDefs = [];
     if (authToken) {
       lexiconDefs = await fetchLexiconDefinitions(selectedText);
     }
-
     const wikiDefs = await fetchWiktionaryDefinition(selectedText);
-
     const allDefinitions = [...lexiconDefs, ...wikiDefs];
     console.log("📝 Définitions combinées :", allDefinitions);
-
     browser.runtime.sendMessage({
       action: "showDefinitions",
       selectedText,
@@ -160,13 +286,9 @@ async function getDefinition(selectedText) {
   }
 }
 
-/**
- * 2) Recherche dans les lexiques pour savoir dans quels lexiques se trouve le mot.
- */
 async function searchInLexicons(selectedText) {
   try {
     console.log("🔎 Recherche dans mes lexiques :", selectedText);
-
     const allDefinitions = await fetchLexiconDefinitions(selectedText);
     if (!allDefinitions || allDefinitions.length === 0) {
       console.log("❌ Aucun lexique trouvé pour ce mot.");
@@ -177,21 +299,17 @@ async function searchInLexicons(selectedText) {
       });
       return;
     }
-
     const lexMap = new Map();
     for (const def of allDefinitions) {
       if (def.lexiconId) {
         lexMap.set(def.lexiconId, def.source);
       }
     }
-
     const foundInLexicons = [];
     for (const [id, name] of lexMap.entries()) {
       foundInLexicons.push({ id, name });
     }
-
     console.log("📩 Envoi du message 'showLexiconResult' avec :", foundInLexicons);
-
     browser.runtime.sendMessage({
       action: "showLexiconResult",
       lexicons: foundInLexicons,
@@ -207,24 +325,3 @@ async function searchInLexicons(selectedText) {
   }
 }
 
-/**
- * 3) Ajouter un mot dans le lexique personnel.
- */
-async function addWordToLexicon(selectedText) {
-  try {
-    console.log("🔍 Ajout du mot à mon lexique :", selectedText);
-    alert(`(Exemple) Le mot "${selectedText}" a été ajouté à votre lexique personnel !`);
-  } catch (error) {
-    console.error("❌ Erreur lors de l'ajout au lexique :", error);
-    alert("❌ Impossible d'ajouter ce mot au lexique.");
-  }
-}
-
-// ─────────────────────────────────────────────────────────────────────────────
-// Écouteur interne pour d’autres messages éventuels
-// ─────────────────────────────────────────────────────────────────────────────
-browser.runtime.onMessage.addListener(async (message) => {
-  if (message.action === "getDefinitionAll") {
-    await getDefinition(message.selectedText);
-  }
-});
-- 
GitLab


From 951838ff1542c5e94f0ce3e0152d52dfd3b51f2b Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Mon, 10 Feb 2025 13:28:03 +0100
Subject: [PATCH 13/23] =?UTF-8?q?Redirection=20ajout=20menu=20navigateur?=
 =?UTF-8?q?=20vers=20barre=20lat=C3=A9rale?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.js"      |  28 +---
 menu_contextuel/browser_context_menu.js | 177 +++++-------------------
 2 files changed, 36 insertions(+), 169 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.js" "b/barre_lat\303\251rale/sidebar.js"
index a6ac96e..6768d2f 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ "b/barre_lat\303\251rale/sidebar.js"
@@ -507,35 +507,17 @@ browser.runtime.onMessage.addListener(async (message) => {
       console.log("📚 Résultat des lexiques reçus :", message.lexicons);
       window.displayLexiconResults(message.lexicons);
       break;
-
+    
+    case "addToLexicon":
+      handleAddWordClick();
+      break;
+      
     case "toggleAuth":
       break;
 
     case "authStatusChanged":
       break;
 
-    case "wordAdded":
-      {
-        // Affichage du message de succès dans la sidebar
-        const lexiconResultElement = document.getElementById("lexiconResult");
-        if (lexiconResultElement) {
-          lexiconResultElement.innerHTML +=
-            "<br>✅ Mot <strong>" + message.selectedWord + "</strong> ajouté avec succès dans : " +
-            message.lexiconIds.join(", ") + ".";
-        }
-      }
-      break;
-      
-    case "wordAddFailed":
-      {
-        // Affichage du message d'erreur dans la sidebar
-        const lexiconResultElement = document.getElementById("lexiconResult");
-        if (lexiconResultElement) {
-          lexiconResultElement.textContent = "Erreur lors de l'ajout du mot : " + message.error;
-        }
-      }
-      break;
-
     default:
       console.warn("⚠️ Action inconnue reçue :", message.action);
   }
diff --git a/menu_contextuel/browser_context_menu.js b/menu_contextuel/browser_context_menu.js
index 8528524..4f9f7c6 100644
--- a/menu_contextuel/browser_context_menu.js
+++ b/menu_contextuel/browser_context_menu.js
@@ -34,54 +34,12 @@ async function createContextMenu() {
       icons: { "16": "icons/quel_lexique.png" },
     });
 
-    // Menu parent pour ajouter le mot dans les lexiques choisis
+    // Item 2 : Ajouter le mot au(x) lexique(s) de l’utilisateur
     browser.contextMenus.create({
-      id: "parentAddLexicon",
-      title: "Ajouter ce mot à…",
+      id: "addToLexicon",
+      title: "Ajouter ce mot à mes lexiques",
       contexts: ["selection"],
-    });
-
-    // Récupérer dynamiquement les lexiques
-    let lexicons = [];
-    try {
-      lexicons = await window.getLexicons(authToken);
-    } catch (error) {
-      console.error("Erreur lors de la récupération des lexiques :", error);
-    }
-
-    if (Array.isArray(lexicons) && lexicons.length > 0) {
-      lexicons.forEach(lexicon => {
-        let title = "";
-        if (lexicon.category === "User") {
-          title = `Lexique personnel (${(lexicon.user && lexicon.user.pseudo) || "Inconnu"}) [${lexicon.id}]`;
-        } else {
-          title = `Lexique de groupe (${(lexicon.group && lexicon.group.name) || "Inconnu"}) [${lexicon.id}]`;
-        }
-        browser.contextMenus.create({
-          id: `addWord_${lexicon.id}`,
-          title: title,
-          type: "checkbox",
-          contexts: ["selection"],
-          parentId: "parentAddLexicon",
-          checked: false
-        });
-      });
-    } else {
-      browser.contextMenus.create({
-        id: "noLexiconsFound",
-        title: "Aucun lexique trouvé",
-        contexts: ["selection"],
-        parentId: "parentAddLexicon",
-        enabled: false
-      });
-    }
-
-    // Item de confirmation pour lancer l'ajout dans les lexiques sélectionnés
-    browser.contextMenus.create({
-      id: "confirmAddWord",
-      title: "Confirmer l'ajout",
-      contexts: ["selection"],
-      parentId: "parentAddLexicon",
+      icons: { "16": "icons/ajout_lexique.png" },
     });
   }
 
@@ -151,9 +109,33 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
     console.warn("Aucun texte sélectionné pour cette action :", info.menuItemId);
     return;
   }
+
   const selectedText = info.selectionText.trim();
   console.log(`📩 Texte sélectionné : ${selectedText}`);
 
+  // Item "Ajouter ce mot à mes lexiques"
+  if (info.menuItemId === "addToLexicon") {
+    if (!authToken) {
+      alert("⚠️ Vous devez être connecté pour ajouter un mot à un lexique.");
+      return;
+    }
+    browser.runtime.sendMessage({
+      action: "addToLexicon",
+      selectedText,
+    });
+    return;
+  }
+
+  // Item "Obtenir une définition"
+  if (info.menuItemId === "getDefinition") {
+    await browser.runtime.sendMessage({
+      action: "getDefinition",
+      selectedText,
+    });
+    return;
+  }
+
+  // Item "Rechercher dans mes lexiques"
   switch (info.menuItemId) {
     case "searchInLexicons":
       if (!authToken) {
@@ -162,106 +144,9 @@ browser.contextMenus.onClicked.addListener(async (info, tab) => {
       }
       await searchInLexicons(selectedText);
       break;
-
-    case "confirmAddWord":
-      if (!authToken) {
-        alert("⚠️ Vous devez être connecté pour utiliser cette fonction.");
-        return;
-      }
-      if (!selectedText || selectedText === "Aucun mot sélectionné") {
-        console.warn("⚠️ Aucun mot à ajouter.");
-        browser.runtime.sendMessage({
-          action: "wordAddFailed",
-          error: "Aucun mot à ajouter."
-        });
-        return;
-      }
-      if (selectedLexicons.size === 0) {
-        alert("Veuillez sélectionner au moins un lexique.");
-        return;
-      }
-      {
-        // Vérifier si le mot existe déjà dans les lexiques sélectionnés
-        let definitions = [];
-        try {
-          definitions = await window.fetchLexiconDefinitions(selectedText);
-        } catch (error) {
-          console.error("Erreur lors de la récupération des définitions pour vérification :", error);
-        }
-        const existingLexiconIds = new Set();
-        if (Array.isArray(definitions)) {
-          for (const def of definitions) {
-            if (selectedLexicons.has(def.lexiconId)) {
-              existingLexiconIds.add(def.lexiconId);
-            }
-          }
-        }
-        if (existingLexiconIds.size > 0) {
-          alert(`Le mot "${selectedText}" existe déjà dans le(s) lexique(s) : ${Array.from(existingLexiconIds).join(", ")}`);
-          browser.runtime.sendMessage({
-            action: "wordAlreadyExists",
-            selectedWord: selectedText,
-            lexiconIds: Array.from(existingLexiconIds)
-          });
-          return;
-        }
-        // On détermine quels lexiques ajouter (ceux non existants)
-        const lexiconsToAdd = Array.from(selectedLexicons).filter(id => !existingLexiconIds.has(id));
-        if (lexiconsToAdd.length === 0) {
-          return; // Rien à ajouter
-        }
-        // Envoi de la requête d'ajout
-        try {
-          console.log(`📡 Envoi de l'ajout du mot "${selectedText}" dans le(s) lexique(s) :`, lexiconsToAdd);
-          const result = await window.AddWord(authToken, selectedText, lexiconsToAdd, false);
-          console.log("✅ Réponse API :", result);
-          await browser.runtime.sendMessage({ action: "refreshUI" });
-          browser.runtime.sendMessage({
-            action: "wordAdded",
-            selectedWord: selectedText,
-            lexiconIds: lexiconsToAdd,
-            result
-          });
-          // Réinitialiser la sélection après ajout
-          selectedLexicons.clear();
-        } catch (error) {
-          console.error("❌ Erreur lors de l’ajout du mot :", error);
-          alert("❌ Une erreur est survenue lors de l’ajout du mot : " + error.message);
-          browser.runtime.sendMessage({
-            action: "wordAddFailed",
-            selectedWord: selectedText,
-            lexiconIds: Array.from(selectedLexicons),
-            error: error.message
-          });
-        }
-      }
-      break;
-
-    default:
-      // Gérer les items de type "checkbox"
-      if (info.menuItemId.startsWith("addWord_")) {
-        const lexiconId = parseInt(info.menuItemId.replace("addWord_", ""), 10);
-        if (isNaN(lexiconId)) {
-          console.error("❌ ID de lexique invalide :", info.menuItemId);
-          return;
-        }
-        if (info.checked) {
-          selectedLexicons.add(lexiconId);
-        } else {
-          selectedLexicons.delete(lexiconId);
-        }
-        console.log("Lexicons sélectionnés :", Array.from(selectedLexicons));
-      } else if (info.menuItemId === "getDefinition") {
-        await browser.runtime.sendMessage({
-          action: "getDefinition",
-          selectedText: info.selectionText.trim(),
-        });
-        return;
-      } else {
-        console.error(`❌ Action inconnue : ${info.menuItemId}`);
-      }
-      break;
-  }
+    }
+  
+  console.error(`❌ Action inconnue : ${info.menuItemId}`);
 });
 
 // ─────────────────────────────────────────────────────────────────────────────
-- 
GitLab


From 025f01fa50dc85ff76c981fde1424a5b583be8ce Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Mon, 10 Feb 2025 15:37:55 +0100
Subject: [PATCH 14/23] =?UTF-8?q?Bouton=20ajouter=20menu=20contextuel=20pe?=
 =?UTF-8?q?rsonnalis=C3=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 "barre_lat\303\251rale/sidebar.html"   |   3 +
 menu_contextuel/custom_context_menu.js | 214 +++++++++++++++++--------
 2 files changed, 146 insertions(+), 71 deletions(-)

diff --git "a/barre_lat\303\251rale/sidebar.html" "b/barre_lat\303\251rale/sidebar.html"
index 28f7552..6724c96 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ "b/barre_lat\303\251rale/sidebar.html"
@@ -309,6 +309,9 @@
     .lexicon-content {
       margin-top: 5px;
     }
+    .lexicon-option {
+      margin-right: -10px;
+    }
     #mesLexiquesList {
       display: inline;
       padding: 0;
diff --git a/menu_contextuel/custom_context_menu.js b/menu_contextuel/custom_context_menu.js
index 510295e..1852073 100644
--- a/menu_contextuel/custom_context_menu.js
+++ b/menu_contextuel/custom_context_menu.js
@@ -26,6 +26,19 @@ async function loadAuthToken() {
   }
 }
 
+/**
+ * Récupère les lexiques via l'API.
+ * On utilise getLexicons(authToken, "fr") et on vérifie si la réponse se trouve dans response.data.
+ */
+async function getLexicons(authToken, language = 'fr') {
+  const userId = 4;
+  const baseUrl = "https://babalex.lezinter.net/api/lexicon/search";
+  const url = `${baseUrl}?user_id=${userId}&language=${encodeURIComponent(language)}`;
+  const response = await callApi(url, authToken);
+  console.log("Réponse API dans getLexicons :", response);
+  return Array.isArray(response) ? response : (response.data || []);
+}
+
 /**
  * Crée le menu contextuel personnalisé (whiteBox) s'il n'existe pas déjà.
  */
@@ -34,8 +47,7 @@ function injectWhiteBox() {
   if (!whiteBox) {
     whiteBox = document.createElement("div");
     whiteBox.id = WHITE_BOX_ID;
-
-    // Définition de styles essentiels pour le positionnement et la visibilité
+    // Styles essentiels
     whiteBox.style.position = "absolute";
     whiteBox.style.zIndex = "9999";
     whiteBox.style.backgroundColor = "#fff";
@@ -43,26 +55,24 @@ function injectWhiteBox() {
     whiteBox.style.padding = "5px";
     whiteBox.style.borderRadius = "4px";
     whiteBox.style.boxShadow = "0px 2px 10px rgba(0,0,0,0.2)";
-
     // Génération des URLs des icônes
     const addLexiconPath = browser.runtime.getURL("icons/ajout_lexique.png");
     const getDefinitionPath = browser.runtime.getURL("icons/definition.png");
     const loginPath = browser.runtime.getURL("icons/connexion.png");
-
-    // Construction du HTML
+    // Construction du HTML du menu contextuel
     whiteBox.innerHTML = `
       <p id="selectedWord" style="margin: 0; padding: 0;">Mot sélectionné : Aucun</p>
       <hr style="border: 0; height: 1px; background-color: #323046; margin: 8px 0;">
       <div style="display: flex; flex-wrap: wrap; justify-content: center;">
-        <!-- Bouton 1 - Ajouter au lexique -->
+        <!-- Bouton : Ajouter au lexique -->
         <div class="icon-container" title="Ajouter ce mot à un lexique">
           <img src="${addLexiconPath}" alt="Ajouter au lexique" class="icon" id="addLexiconButton">
         </div>
-        <!-- Bouton 2 - Définition (Babalex + Wiki) -->
+        <!-- Bouton : Obtenir une définition -->
         <div class="icon-container" title="Obtenir la définition">
           <img src="${getDefinitionPath}" alt="Obtenir la définition" class="icon" id="getDefinitionButton">
         </div>
-        <!-- Bouton 3 - Connexion -->
+        <!-- Bouton : Connexion -->
         <div class="icon-container" title="Connectez-vous à BaLex">
           <img src="${loginPath}" alt="Se connecter" class="icon" id="loginButton" style="display: none;">
         </div>
@@ -71,42 +81,43 @@ function injectWhiteBox() {
     document.body.appendChild(whiteBox);
     setupWhiteBoxActions();
   }
+  // Empêcher la propagation des clics dans le menu
+  whiteBox.addEventListener("mouseup", (e) => {
+    e.stopPropagation();
+  });
   return whiteBox;
 }
 
 /**
- * Renvoie le whiteBox s'il existe, ou le crée via injectWhiteBox().
+ * Renvoie le whiteBox s'il existe, ou le crée.
  */
 function getOrCreateWhiteBox() {
   return document.getElementById(WHITE_BOX_ID) || injectWhiteBox();
 }
 
 /**
- * Configure les actions/boutons du menu contextuel.
+ * Configure les actions des boutons du menu contextuel.
  */
 function setupWhiteBoxActions() {
   const addLexiconBtn = document.getElementById("addLexiconButton");
   const getDefinitionBtn = document.getElementById("getDefinitionButton");
   const loginBtn = document.getElementById("loginButton");
 
-  // Bouton : Ajouter le mot au lexique personnel
-  addLexiconBtn.onclick = async () => {
-    const selectedText = getSelectedWord();
-    console.log("🔍 Ajout au lexique :", selectedText);
+  // Bouton : Ajouter le mot au lexique
+  addLexiconBtn.onclick = async (e) => {
+    e.stopPropagation();
+    e.preventDefault();
+    const selectedText = getSelectedWord().trim();
+    console.log("🔍 Bouton Ajouter au lexique cliqué avec le mot :", selectedText);
     if (!selectedText) return;
-
     if (authToken) {
-      await searchLexicon(selectedText);
+      await showPicker(e, selectedText);
     } else {
-      sendNotification(
-        "Connexion requise",
-        "⚠️ Veuillez vous connecter pour utiliser cette fonction.",
-        "icons/connexion.png"
-      );
+      alert("Vous devez être connecté pour ajouter un mot.");
     }
   };
 
-  // Bouton : Obtenir une définition (Babalex + Wiktionnaire)
+  // Bouton : Obtenir une définition
   getDefinitionBtn.onclick = () => {
     const selectedText = getSelectedWord().trim();
     if (selectedText) {
@@ -119,20 +130,14 @@ function setupWhiteBoxActions() {
 
   // Bouton : Connexion
   loginBtn.onclick = () => {
-    sendNotification(
-      "Redirection",
-      "Vous allez être redirigé(e) vers la page de connexion.",
-      "icons/connexion.png"
-    );
     browser.runtime.sendMessage({ action: "toggleAuth" });
   };
 }
 
 /**
- * Met à jour la visibilité des boutons en fonction de l'état d'authentification.
+ * Met à jour la visibilité des boutons du menu selon l'authentification.
  */
 function updateMenuVisibility() {
-  // S'assurer que le whiteBox existe
   getOrCreateWhiteBox();
   const addLexiconBtn = document.getElementById("addLexiconButton");
   const getDefinitionBtn = document.getElementById("getDefinitionButton");
@@ -144,12 +149,10 @@ function updateMenuVisibility() {
   }
 
   if (authToken) {
-    // Utilisateur connecté => afficher "Ajouter" et "Définition", masquer "Connexion"
     addLexiconBtn.style.display = "inline-block";
     getDefinitionBtn.style.display = "inline-block";
     loginBtn.style.display = "none";
   } else {
-    // Utilisateur déconnecté => masquer "Ajouter", afficher "Définition" et "Connexion"
     addLexiconBtn.style.display = "none";
     getDefinitionBtn.style.display = "inline-block";
     loginBtn.style.display = "inline-block";
@@ -157,7 +160,7 @@ function updateMenuVisibility() {
 }
 
 /**
- * Récupère le mot affiché dans #selectedWord.
+ * Récupère le texte affiché dans #selectedWord.
  */
 function getSelectedWord() {
   const selectedWordElement = document.getElementById("selectedWord");
@@ -170,18 +173,17 @@ function getSelectedWord() {
 function showWhiteBox(event, selectedText) {
   const whiteBox = getOrCreateWhiteBox();
   const selectedWordElement = document.getElementById("selectedWord");
-  selectedWordElement.textContent = `${selectedText}`;
+  selectedWordElement.textContent = selectedText;
 
-  // Calculer la position du menu en fonction de la sélection
   const selection = window.getSelection();
-  if (!selection.rangeCount) return; // sécurité au cas où
+  if (!selection.rangeCount) return;
   const range = selection.getRangeAt(0);
   const rect = range.getBoundingClientRect();
   const top = rect.bottom + window.scrollY;
   const left = rect.right + window.scrollX;
 
-  whiteBox.style.left = `${left}px`;
-  whiteBox.style.top = `${top}px`;
+  whiteBox.style.left = left + "px";
+  whiteBox.style.top = top + "px";
   whiteBox.style.display = "block";
 
   console.log("Affichage du menu contextuel avec le mot :", selectedText);
@@ -195,15 +197,15 @@ function hideWhiteBox() {
   }
 }
 
-// === Écoute des événements de sélection de texte (mouseup) ===
+// Écoute globale pour la sélection de texte
 document.addEventListener("mouseup", (event) => {
+  // Si le clic se fait à l'intérieur du whiteBox, ne rien faire
+  if (event.target.closest("#whiteBox")) return;
   const selectedText = window.getSelection().toString().trim();
   if (selectedText) {
-    console.log("Événement de sélection détecté. Texte sélectionné :", selectedText);
+    console.log("Texte sélectionné :", selectedText);
     getOrCreateWhiteBox();
     showWhiteBox(event, selectedText);
-
-    // Envoi du mot sélectionné au background
     browser.runtime.sendMessage({
       action: "mot_selectionne",
       selectedText,
@@ -213,13 +215,11 @@ document.addEventListener("mouseup", (event) => {
   }
 });
 
-// Réécoute des messages envoyés
+// Écoute des messages entrants
 browser.runtime.onMessage.addListener((message) => {
   if (message.action === "refreshUI") {
     console.log("🔄 Mise à jour du menu contextuel personnalisé.");
-    loadAuthToken().then(() => {
-      updateMenuVisibility();
-    });
+    loadAuthToken().then(updateMenuVisibility);
   }
 });
 
@@ -228,44 +228,116 @@ loadAuthToken().then(() => {
   getOrCreateWhiteBox();
   updateMenuVisibility();
 });
-
 browser.storage.onChanged.addListener((changes) => {
   if (changes.accessToken) {
-    console.log("🔄 Token changé dans le stockage, mise à jour du menu personnalisé.");
-    loadAuthToken().then(() => {
-      updateMenuVisibility();
-    });
+    console.log("🔄 Token modifié dans le stockage, mise à jour du menu contextuel.");
+    loadAuthToken().then(updateMenuVisibility);
   }
 });
 
+
 // ─────────────────────────────────────────────────────────────────────────────
-// ▌ Fonctions d'API Babalex pour l'ajout ou la vérification d'un mot
+// Fonctions d'API pour l'ajout d'un mot via le picker
 // ─────────────────────────────────────────────────────────────────────────────
 
-async function searchLexicon(selectedText) {
-  console.log("🔄 Recherche dans le lexique personnel pour :", selectedText);
-  try {
-    const lexicons = await getUserLexicons(authToken);
-    console.log("📚 Lexiques récupérés :", lexicons);
-
-    const frenchLexicon = lexicons.find((lexicon) => lexicon.language === "fr");
-    if (!frenchLexicon) {
-      alert("⚠️ Aucun lexique français trouvé.");
-      return;
-    }
+/**
+ * Crée (ou récupère) le picker de sélection des lexiques.
+ */
+function createPicker() {
+  let picker = document.getElementById("lexiconPicker");
+  if (!picker) {
+    picker = document.createElement("div");
+    picker.id = "lexiconPicker";
+    // Styles pour le picker
+    picker.style.position = "absolute";
+    picker.style.zIndex = "10000";
+    picker.style.backgroundColor = "rgba(255, 255, 255, 0.95)";
+    picker.style.border = "1px solid #ccc";
+    picker.style.padding = "10px";
+    picker.style.borderRadius = "4px";
+    picker.style.boxShadow = "0 2px 10px rgba(0,0,0,0.3)";
+    picker.style.display = "none";
+    document.body.appendChild(picker);
+  }
+  return picker;
+}
 
-    const entries = await getLexiconEntriesID(authToken, frenchLexicon.id);
-    const isWordPresent = entries.some(
-      (entry) => entry.graphy.toLowerCase() === selectedText.toLowerCase()
-    );
+/**
+ * Affiche le picker pour choisir le lexique dans lequel ajouter le mot.
+ * Pour chaque lexique, vérifie si le mot existe déjà dans ce lexique en appelant fetchLexiconDefinitions.
+ * S'il n'existe pas, appelle window.AddWord pour l'ajouter.
+ */
+async function showPicker(event, selectedText) {
+  console.log("showPicker appelé avec", event, selectedText);
+  const picker = createPicker();
+  picker.innerHTML = ""; // Vider le picker
 
-    if (isWordPresent) {
-      alert(`✅ Le mot "${selectedText}" est présent dans votre lexique personnel.`);
+  try {
+    const lexicons = await getLexicons(authToken, "fr");
+    console.log("Lexicons récupérés :", lexicons);
+    if (!Array.isArray(lexicons) || lexicons.length === 0) {
+      picker.innerHTML = "<p>Aucun lexique trouvé.</p>";
     } else {
-      alert(`❌ Le mot "${selectedText}" n'est pas présent dans votre lexique personnel.`);
+      lexicons.forEach(lex => {
+        // Extraction des propriétés en se basant sur la logique de fetchLexicons()
+        const id = lex.id;
+        const name = lex.category === "User"
+          ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
+          : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
+        const iconURL = lex.iconURL || browser.runtime.getURL("icons/default_lexicon.png");
+
+        const iconDiv = document.createElement("div");
+        iconDiv.className = "lexicon-option";
+        iconDiv.dataset.lexiconId = id;
+        iconDiv.style.display = "inline-block";
+        iconDiv.style.margin = "5px";
+        iconDiv.style.cursor = "pointer";
+        iconDiv.style.position = "relative";
+
+        const iconImg = document.createElement("img");
+        iconImg.src = iconURL;
+        iconImg.alt = name;
+        iconImg.title = name;
+        iconImg.style.width = "32px";
+        iconImg.style.height = "32px";
+
+        iconDiv.appendChild(iconImg);
+        picker.appendChild(iconDiv);
+
+        iconDiv.addEventListener("click", async () => {
+          console.log(`Tentative d'ajout du mot "${selectedText}" au lexique ${id} (${name})`);
+          try {
+            // Vérifier si le mot existe déjà dans ce lexique
+            let definitions = [];
+            try {
+              definitions = await fetchLexiconDefinitions(selectedText);
+            } catch (err) {
+              console.error("Erreur lors de la récupération des définitions :", err);
+            }
+            const exists = Array.isArray(definitions) && definitions.some(def => def.lexiconId === id);
+            if (exists) {
+              alert(`Le mot "${selectedText}" existe déjà dans le lexique ${name}.`);
+            } else {
+              await window.AddWord(authToken, selectedText, [id], false);
+              alert(`Le mot "${selectedText}" a été ajouté dans le lexique ${name}.`);
+            }
+            picker.style.display = "none";
+          } catch (error) {
+            console.error("Erreur lors de l'ajout du mot :", error);
+            alert(`Erreur : ${error.message}`);
+          }
+        });
+      });
     }
+
+    // Positionner le picker en fonction de l'événement
+    console.log("Positionnement du picker en X:", event.pageX, "Y:", event.pageY);
+    picker.style.left = event.pageX + "px";
+    picker.style.top = event.pageY + "px";
+    picker.style.display = "block";
   } catch (error) {
-    console.error("❌ Erreur lors de la recherche dans le lexique :", error);
-    alert(`Erreur lors de la recherche : ${error.message}`);
+    console.error("Erreur lors de la récupération des lexiques :", error);
+    picker.innerHTML = "<p>Erreur lors du chargement des lexiques.</p>";
+    picker.style.display = "block";
   }
 }
-- 
GitLab


From 08d0cad8d01dbbcf1ccc87066138bf119d12a78d Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Tue, 11 Feb 2025 15:34:06 +0100
Subject: [PATCH 15/23] =?UTF-8?q?R=C3=A9organisation=20des=20dossiers/fich?=
 =?UTF-8?q?iers?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 manifest.json                                 |  33 ++++++++----------
 {icons => src/assets/icons}/ajout_lexique.png | Bin
 {icons => src/assets/icons}/connexion.png     | Bin
 {icons => src/assets/icons}/definition.png    | Bin
 .../assets/icons}/definition_wiktionnaire.png | Bin
 {icons => src/assets/icons}/feutre.png        | Bin
 {icons => src/assets/icons}/logo.png          | Bin
 {icons => src/assets/icons}/quel_lexique.png  | Bin
 .../assets/icons}/recherche_lexique.png       | Bin
 {background => src/background}/background.js  |   0
 .../context_menu}/browser_context_menu.js     |   0
 .../context_menu}/custom_context_menu.css     |   0
 .../context_menu}/custom_context_menu.js      |   8 ++---
 {menu_extension => src/options}/options.html  |   0
 {menu_extension => src/options}/options.js    |   0
 {menu_extension => src/popup}/popup.html      |   0
 {menu_extension => src/popup}/popup.js        |   0
 .../sidebar.html" => src/sidebar/sidebar.html |   4 +--
 .../sidebar.js" => src/sidebar/sidebar.js     |   2 +-
 api.js => src/utils/api.js                    |   0
 definitions.js => src/utils/definitions.js    |   0
 21 files changed, 22 insertions(+), 25 deletions(-)
 rename {icons => src/assets/icons}/ajout_lexique.png (100%)
 rename {icons => src/assets/icons}/connexion.png (100%)
 rename {icons => src/assets/icons}/definition.png (100%)
 rename {icons => src/assets/icons}/definition_wiktionnaire.png (100%)
 rename {icons => src/assets/icons}/feutre.png (100%)
 rename {icons => src/assets/icons}/logo.png (100%)
 rename {icons => src/assets/icons}/quel_lexique.png (100%)
 rename {icons => src/assets/icons}/recherche_lexique.png (100%)
 rename {background => src/background}/background.js (100%)
 rename {menu_contextuel => src/context_menu}/browser_context_menu.js (100%)
 rename {menu_contextuel => src/context_menu}/custom_context_menu.css (100%)
 rename {menu_contextuel => src/context_menu}/custom_context_menu.js (97%)
 rename {menu_extension => src/options}/options.html (100%)
 rename {menu_extension => src/options}/options.js (100%)
 rename {menu_extension => src/popup}/popup.html (100%)
 rename {menu_extension => src/popup}/popup.js (100%)
 rename "barre_lat\303\251rale/sidebar.html" => src/sidebar/sidebar.html (99%)
 rename "barre_lat\303\251rale/sidebar.js" => src/sidebar/sidebar.js (99%)
 rename api.js => src/utils/api.js (100%)
 rename definitions.js => src/utils/definitions.js (100%)

diff --git a/manifest.json b/manifest.json
index b652cb0..642aaa8 100644
--- a/manifest.json
+++ b/manifest.json
@@ -20,58 +20,55 @@
 
   "background": {
     "scripts": [
-      "background/background.js", 
-      "definitions.js",
-      "api.js",
-      "menu_contextuel/browser_context_menu.js"
+      "src/background/background.js", 
+      "src/utils/definitions.js",
+      "src/utils/api.js",
+      "src/context_menu/browser_context_menu.js"
     ],
     "persistent": true
   },
 
   "browser_action": {
-    "default_popup": "menu_extension/popup.html",
+    "default_popup": "src/popup/popup.html",
     "default_icon": {
-      "16": "icons/logo.png"
+      "16": "src/assets/icons/logo.png"
     },
     "default_title": "ff2BaLex"
   },
 
   "options_ui": {
-    "page": "menu_extension/options.html",
+    "page": "src/options/options.html",
     "open_in_tab": false
   },
 
   "sidebar_action": {
     "default_title": "BaLex",
-    "default_panel": "barre_latérale/sidebar.html",
+    "default_panel": "src/sidebar/sidebar.html",
     "default_icon": {
-      "16": "icons/logo.png",
-      "48": "icons/icon-48.png"
+      "16": "src/assets/icons/logo.png",
+      "48": "src/assets/icons/icon-48.png"
     }
   },
 
   "content_scripts": [
     {
       "matches": ["<all_urls>"], 
-      "js": ["api.js"]
+      "js": ["src/utils/api.js"]
     },
     {
       "matches": ["<all_urls>"], 
-      "js": ["menu_contextuel/custom_context_menu.js"],
-      "css": ["menu_contextuel/custom_context_menu.css"],
+      "js": ["src/context_menu/custom_context_menu.js"],
+      "css": ["src/context_menu/custom_context_menu.css"],
       "run_at": "document_end"
     }
   ],
 
   "web_accessible_resources": [
-    "icons/*.png",
-    "menu_extension/*",
-    "barre_latérale/*",
-    "menu_contextuel/*"
+    "src/*"
   ],
 
   
   "icons": {
-    "16": "icons/logo.png"
+    "16": "src/assets/icons/logo.png"
   }
 }
diff --git a/icons/ajout_lexique.png b/src/assets/icons/ajout_lexique.png
similarity index 100%
rename from icons/ajout_lexique.png
rename to src/assets/icons/ajout_lexique.png
diff --git a/icons/connexion.png b/src/assets/icons/connexion.png
similarity index 100%
rename from icons/connexion.png
rename to src/assets/icons/connexion.png
diff --git a/icons/definition.png b/src/assets/icons/definition.png
similarity index 100%
rename from icons/definition.png
rename to src/assets/icons/definition.png
diff --git a/icons/definition_wiktionnaire.png b/src/assets/icons/definition_wiktionnaire.png
similarity index 100%
rename from icons/definition_wiktionnaire.png
rename to src/assets/icons/definition_wiktionnaire.png
diff --git a/icons/feutre.png b/src/assets/icons/feutre.png
similarity index 100%
rename from icons/feutre.png
rename to src/assets/icons/feutre.png
diff --git a/icons/logo.png b/src/assets/icons/logo.png
similarity index 100%
rename from icons/logo.png
rename to src/assets/icons/logo.png
diff --git a/icons/quel_lexique.png b/src/assets/icons/quel_lexique.png
similarity index 100%
rename from icons/quel_lexique.png
rename to src/assets/icons/quel_lexique.png
diff --git a/icons/recherche_lexique.png b/src/assets/icons/recherche_lexique.png
similarity index 100%
rename from icons/recherche_lexique.png
rename to src/assets/icons/recherche_lexique.png
diff --git a/background/background.js b/src/background/background.js
similarity index 100%
rename from background/background.js
rename to src/background/background.js
diff --git a/menu_contextuel/browser_context_menu.js b/src/context_menu/browser_context_menu.js
similarity index 100%
rename from menu_contextuel/browser_context_menu.js
rename to src/context_menu/browser_context_menu.js
diff --git a/menu_contextuel/custom_context_menu.css b/src/context_menu/custom_context_menu.css
similarity index 100%
rename from menu_contextuel/custom_context_menu.css
rename to src/context_menu/custom_context_menu.css
diff --git a/menu_contextuel/custom_context_menu.js b/src/context_menu/custom_context_menu.js
similarity index 97%
rename from menu_contextuel/custom_context_menu.js
rename to src/context_menu/custom_context_menu.js
index 1852073..011478f 100644
--- a/menu_contextuel/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -56,9 +56,9 @@ function injectWhiteBox() {
     whiteBox.style.borderRadius = "4px";
     whiteBox.style.boxShadow = "0px 2px 10px rgba(0,0,0,0.2)";
     // Génération des URLs des icônes
-    const addLexiconPath = browser.runtime.getURL("icons/ajout_lexique.png");
-    const getDefinitionPath = browser.runtime.getURL("icons/definition.png");
-    const loginPath = browser.runtime.getURL("icons/connexion.png");
+    const addLexiconPath = browser.runtime.getURL("src/assets/icons/ajout_lexique.png");
+    const getDefinitionPath = browser.runtime.getURL("src/assets/icons/definition.png");
+    const loginPath = browser.runtime.getURL("src/assets/icons/connexion.png");
     // Construction du HTML du menu contextuel
     whiteBox.innerHTML = `
       <p id="selectedWord" style="margin: 0; padding: 0;">Mot sélectionné : Aucun</p>
@@ -284,7 +284,7 @@ async function showPicker(event, selectedText) {
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
-        const iconURL = lex.iconURL || browser.runtime.getURL("icons/default_lexicon.png");
+        const iconURL = lex.iconURL || browser.runtime.getURL("src/assets/icons/default_lexicon.png");
 
         const iconDiv = document.createElement("div");
         iconDiv.className = "lexicon-option";
diff --git a/menu_extension/options.html b/src/options/options.html
similarity index 100%
rename from menu_extension/options.html
rename to src/options/options.html
diff --git a/menu_extension/options.js b/src/options/options.js
similarity index 100%
rename from menu_extension/options.js
rename to src/options/options.js
diff --git a/menu_extension/popup.html b/src/popup/popup.html
similarity index 100%
rename from menu_extension/popup.html
rename to src/popup/popup.html
diff --git a/menu_extension/popup.js b/src/popup/popup.js
similarity index 100%
rename from menu_extension/popup.js
rename to src/popup/popup.js
diff --git "a/barre_lat\303\251rale/sidebar.html" b/src/sidebar/sidebar.html
similarity index 99%
rename from "barre_lat\303\251rale/sidebar.html"
rename to src/sidebar/sidebar.html
index 6724c96..2327900 100644
--- "a/barre_lat\303\251rale/sidebar.html"
+++ b/src/sidebar/sidebar.html
@@ -4,8 +4,8 @@
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>BaLex - Barre Latérale</title>
-  <script src="../api.js" defer></script>
-  <script src="../definitions.js" defer></script>
+  <script src="../utils/api.js" defer></script>
+  <script src="../utils/definitions.js" defer></script>
   <script src="sidebar.js" defer></script>
   
   <style>
diff --git "a/barre_lat\303\251rale/sidebar.js" b/src/sidebar/sidebar.js
similarity index 99%
rename from "barre_lat\303\251rale/sidebar.js"
rename to src/sidebar/sidebar.js
index 6768d2f..c5707e9 100644
--- "a/barre_lat\303\251rale/sidebar.js"
+++ b/src/sidebar/sidebar.js
@@ -254,7 +254,7 @@ function displayLexiconsWithCheckbox(lexicons) {
     highlightButton.dataset.active = active ? "true" : "false";
 
     const feutreIcon = document.createElement("img");
-    feutreIcon.src = "/icons/feutre.png";
+    feutreIcon.src = "../assets/icons/feutre.png";
     feutreIcon.alt = "Feutre";
     feutreIcon.className = "feutre-icon";
 
diff --git a/api.js b/src/utils/api.js
similarity index 100%
rename from api.js
rename to src/utils/api.js
diff --git a/definitions.js b/src/utils/definitions.js
similarity index 100%
rename from definitions.js
rename to src/utils/definitions.js
-- 
GitLab


From 3f4965ad0d5e7f93b22f397a80a924d0091a8920 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Tue, 11 Feb 2025 17:38:46 +0100
Subject: [PATCH 16/23] =?UTF-8?q?Ic=C3=B4nes=20lexiques?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 manifest.json                           | 11 +++--
 src/assets/lexicon_icon.js              | 52 +++++++++++++++++++++
 src/context_menu/custom_context_menu.js | 62 +++++++++----------------
 src/sidebar/sidebar.html                |  1 +
 src/sidebar/sidebar.js                  | 12 +++--
 src/utils/api.js                        |  4 +-
 src/utils/definitions.js                |  2 +-
 7 files changed, 92 insertions(+), 52 deletions(-)
 create mode 100644 src/assets/lexicon_icon.js

diff --git a/manifest.json b/manifest.json
index 642aaa8..a74107e 100644
--- a/manifest.json
+++ b/manifest.json
@@ -53,11 +53,12 @@
   "content_scripts": [
     {
       "matches": ["<all_urls>"], 
-      "js": ["src/utils/api.js"]
-    },
-    {
-      "matches": ["<all_urls>"], 
-      "js": ["src/context_menu/custom_context_menu.js"],
+      "js": [
+        "src/assets/lexicon_icon.js",
+        "src/utils/api.js",
+        "src/utils/definitions.js",
+        "src/sidebar/sidebar.js",
+        "src/context_menu/custom_context_menu.js"],
       "css": ["src/context_menu/custom_context_menu.css"],
       "run_at": "document_end"
     }
diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
new file mode 100644
index 0000000..021073d
--- /dev/null
+++ b/src/assets/lexicon_icon.js
@@ -0,0 +1,52 @@
+console.log("lexicon_icon.js chargé");
+
+/**
+ * Génère une couleur hexadécimale aléatoire (#RRGGBB).
+ * @returns {string} Une couleur hexadécimale, ex: "#A1B2C3".
+ */
+function generateRandomColor() {
+  const letters = '0123456789ABCDEF';
+  let color = '#';
+  for (let i = 0; i < 6; i++) {
+    color += letters[Math.floor(Math.random() * 16)];
+  }
+  return color;
+}
+
+/**
+ * Retourne (ou crée) la couleur associée à un lexique donné.
+ * La couleur est stockée dans l'objet global window.lexiconColors pour la persistance durant la session.
+ * @param {string|number} lexiconId - L'identifiant du lexique.
+ * @returns {string} La couleur associée.
+ */
+function getOrCreateLexiconColor(lexiconId) {
+  // Crée l'objet global s'il n'existe pas déjà.
+  window.lexiconColors = window.lexiconColors || {};
+  if (!window.lexiconColors[lexiconId]) {
+    window.lexiconColors[lexiconId] = generateRandomColor();
+  }
+  return window.lexiconColors[lexiconId];
+}
+
+/**
+ * Crée un élément HTML (div) stylisé en cercle de la couleur donnée.
+ * @param {string} color - Couleur au format "#RRGGBB".
+ * @param {number} [size=32] - Taille (largeur et hauteur) en pixels.
+ * @returns {HTMLElement} Le div stylisé en cercle.
+ */
+function createColorCircle(color, size = 32) {
+  const circle = document.createElement("div");
+  circle.style.width = `${size}px`;
+  circle.style.height = `${size}px`;
+  circle.style.borderRadius = "50%";
+  circle.style.backgroundColor = color;
+  circle.style.border = "1px solid black"; // Optionnel
+  return circle;
+}
+
+// Exposez ces fonctions globalement pour qu'elles soient accessibles dans d'autres scripts.
+window.generateRandomColor = generateRandomColor;
+window.getOrCreateLexiconColor = getOrCreateLexiconColor;
+window.createColorCircle = createColorCircle;
+
+console.log("lexicon_icon.js chargé");
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 011478f..2d38fba 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -1,7 +1,6 @@
 console.log("custom_context_menu.js chargé correctement");
 
 // === Variables globales ===
-let authToken = null;
 const WHITE_BOX_ID = "whiteBox";
 
 // Fonction utilitaire pour envoyer une notification via le background
@@ -26,19 +25,6 @@ async function loadAuthToken() {
   }
 }
 
-/**
- * Récupère les lexiques via l'API.
- * On utilise getLexicons(authToken, "fr") et on vérifie si la réponse se trouve dans response.data.
- */
-async function getLexicons(authToken, language = 'fr') {
-  const userId = 4;
-  const baseUrl = "https://babalex.lezinter.net/api/lexicon/search";
-  const url = `${baseUrl}?user_id=${userId}&language=${encodeURIComponent(language)}`;
-  const response = await callApi(url, authToken);
-  console.log("Réponse API dans getLexicons :", response);
-  return Array.isArray(response) ? response : (response.data || []);
-}
-
 /**
  * Crée le menu contextuel personnalisé (whiteBox) s'il n'existe pas déjà.
  */
@@ -269,7 +255,7 @@ function createPicker() {
  */
 async function showPicker(event, selectedText) {
   console.log("showPicker appelé avec", event, selectedText);
-  const picker = createPicker();
+  const picker = createPicker(); // supposez que createPicker est défini ailleurs dans ce fichier
   picker.innerHTML = ""; // Vider le picker
 
   try {
@@ -279,35 +265,31 @@ async function showPicker(event, selectedText) {
       picker.innerHTML = "<p>Aucun lexique trouvé.</p>";
     } else {
       lexicons.forEach(lex => {
-        // Extraction des propriétés en se basant sur la logique de fetchLexicons()
         const id = lex.id;
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
-        const iconURL = lex.iconURL || browser.runtime.getURL("src/assets/icons/default_lexicon.png");
-
-        const iconDiv = document.createElement("div");
-        iconDiv.className = "lexicon-option";
-        iconDiv.dataset.lexiconId = id;
-        iconDiv.style.display = "inline-block";
-        iconDiv.style.margin = "5px";
-        iconDiv.style.cursor = "pointer";
-        iconDiv.style.position = "relative";
-
-        const iconImg = document.createElement("img");
-        iconImg.src = iconURL;
-        iconImg.alt = name;
-        iconImg.title = name;
-        iconImg.style.width = "32px";
-        iconImg.style.height = "32px";
-
-        iconDiv.appendChild(iconImg);
-        picker.appendChild(iconDiv);
-
-        iconDiv.addEventListener("click", async () => {
+        
+        // Obtenir la couleur et créer le cercle
+        const color = getOrCreateLexiconColor(id);
+        const circleIcon = createColorCircle(color, 32);
+
+        // Crée un conteneur pour l'icône
+        const iconContainer = document.createElement("div");
+        iconContainer.className = "lexicon-option";
+        iconContainer.dataset.lexiconId = id;
+        iconContainer.style.margin = "5px";
+        iconContainer.style.cursor = "pointer";
+        iconContainer.title = name;
+
+        // Ajoute le cercle coloré au conteneur
+        iconContainer.appendChild(circleIcon);
+        picker.appendChild(iconContainer);
+
+        // Écouteur de clic pour ajouter le mot au lexique sélectionné
+        iconContainer.addEventListener("click", async () => {
           console.log(`Tentative d'ajout du mot "${selectedText}" au lexique ${id} (${name})`);
           try {
-            // Vérifier si le mot existe déjà dans ce lexique
             let definitions = [];
             try {
               definitions = await fetchLexiconDefinitions(selectedText);
@@ -330,8 +312,7 @@ async function showPicker(event, selectedText) {
       });
     }
 
-    // Positionner le picker en fonction de l'événement
-    console.log("Positionnement du picker en X:", event.pageX, "Y:", event.pageY);
+    // Positionner et afficher le picker
     picker.style.left = event.pageX + "px";
     picker.style.top = event.pageY + "px";
     picker.style.display = "block";
@@ -341,3 +322,4 @@ async function showPicker(event, selectedText) {
     picker.style.display = "block";
   }
 }
+
diff --git a/src/sidebar/sidebar.html b/src/sidebar/sidebar.html
index 2327900..6d189ef 100644
--- a/src/sidebar/sidebar.html
+++ b/src/sidebar/sidebar.html
@@ -4,6 +4,7 @@
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>BaLex - Barre Latérale</title>
+  <script src="../assets/lexicon_icon.js" defer></script>
   <script src="../utils/api.js" defer></script>
   <script src="../utils/definitions.js" defer></script>
   <script src="sidebar.js" defer></script>
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index c5707e9..e31a0dd 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -3,14 +3,13 @@ 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
 // ─────────────────────────────────────────────────────────────────────────────
-let authToken = null;
-
-window.lexiconMap = lexiconMap;
+let authToken = window.authToken;
 window.authToken = authToken;
 
 // ─────────────────────────────────────────────────────────────────────────────
@@ -170,7 +169,7 @@ async function fetchLexicons() {
     if (!authToken) {
       throw new Error("⚠️ Aucun token disponible. Veuillez vous connecter.");
     }
-
+    console.log("getLexicons type:", typeof getLexicons);
     const lexicons = await getLexicons(authToken, "fr");
     console.log("📚 Réponse brute de l'API :", lexicons);
 
@@ -227,8 +226,11 @@ function displayLexiconsWithCheckbox(lexicons) {
     lexiqueDiv.className = "lexique-item";
 
     // Icône du lexique
+    const color = getOrCreateLexiconColor(lexiconId);
+    const circleIcon = createColorCircle(color, 24);
     const iconDiv = document.createElement("div");
     iconDiv.className = "lexique-icon";
+    iconDiv.appendChild(circleIcon);
 
     const labelSpan = document.createElement("span");
     labelSpan.className = "lexique-label";
diff --git a/src/utils/api.js b/src/utils/api.js
index 72eb48c..c1bc41c 100644
--- a/src/utils/api.js
+++ b/src/utils/api.js
@@ -1,5 +1,5 @@
 console.log("✅ api.js chargé correctement");
-
+window.authToken = null;
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Sélection de texte sur la page
 // ─────────────────────────────────────────────────────────────────────────────
@@ -223,8 +223,10 @@ async function AddWord(authToken, selectedWord, lexiconIds, force = false) {
 
 window.callApi = callApi;
 window.getLexicons = getLexicons;
+console.log("getLexicons exposée, type:", typeof window.getLexicons);
 window.getAllCategoriesLexicons = getAllCategoriesLexicons;
 window.getLexiconEntries = getLexiconEntries;
 window.getAllLexiconWords = getAllLexiconWords;
 window.getWiktionaryDefinition = getWiktionaryDefinition;
 window.AddWord = AddWord;
+
diff --git a/src/utils/definitions.js b/src/utils/definitions.js
index c8832d8..d295160 100644
--- a/src/utils/definitions.js
+++ b/src/utils/definitions.js
@@ -2,7 +2,7 @@
 // ▌ Fonctions pour récupérer/afficher les définitions
 // ─────────────────────────────────────────────────────────────────────────────
 
-const lexiconMap = new Map();
+window.lexiconMap = new Map();
 
 /**
 * Récupère les définitions d'un mot dans les lexiques de l'utilisateur (ex. user_id=4),
-- 
GitLab


From 4062393843b4bf07e67866df6553cbaed824bb04 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Tue, 11 Feb 2025 17:55:00 +0100
Subject: [PATCH 17/23] Association couleurs lexiques

---
 src/assets/lexicon_icon.js               | 23 +++++----
 src/context_menu/browser_context_menu.js |  6 +--
 src/context_menu/custom_context_menu.js  |  7 +--
 src/sidebar/sidebar.js                   | 64 +++++++++++-------------
 4 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 021073d..5fc780a 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -14,18 +14,22 @@ function generateRandomColor() {
 }
 
 /**
- * Retourne (ou crée) la couleur associée à un lexique donné.
- * La couleur est stockée dans l'objet global window.lexiconColors pour la persistance durant la session.
+ * Obtient (ou crée) la couleur associée à un lexique donné en utilisant browser.storage.local.
  * @param {string|number} lexiconId - L'identifiant du lexique.
- * @returns {string} La couleur associée.
+ * @returns {Promise<string>} La couleur associée au lexique.
  */
-function getOrCreateLexiconColor(lexiconId) {
-  // Crée l'objet global s'il n'existe pas déjà.
-  window.lexiconColors = window.lexiconColors || {};
-  if (!window.lexiconColors[lexiconId]) {
-    window.lexiconColors[lexiconId] = generateRandomColor();
+async function getOrCreateLexiconColor(lexiconId) {
+  // Récupère la correspondance stockée dans storage
+  let { lexiconColors } = await browser.storage.local.get("lexiconColors");
+  if (!lexiconColors) {
+    lexiconColors = {};
   }
-  return window.lexiconColors[lexiconId];
+  // Si aucune couleur n'est associée à ce lexiconId, on la génère et on la sauvegarde
+  if (!lexiconColors[lexiconId]) {
+    lexiconColors[lexiconId] = generateRandomColor();
+    await browser.storage.local.set({ lexiconColors });
+  }
+  return lexiconColors[lexiconId];
 }
 
 /**
@@ -49,4 +53,3 @@ window.generateRandomColor = generateRandomColor;
 window.getOrCreateLexiconColor = getOrCreateLexiconColor;
 window.createColorCircle = createColorCircle;
 
-console.log("lexicon_icon.js chargé");
diff --git a/src/context_menu/browser_context_menu.js b/src/context_menu/browser_context_menu.js
index 4f9f7c6..7c24d4a 100644
--- a/src/context_menu/browser_context_menu.js
+++ b/src/context_menu/browser_context_menu.js
@@ -31,7 +31,7 @@ async function createContextMenu() {
       id: "searchInLexicons",
       title: "Rechercher dans mes lexiques",
       contexts: ["selection"],
-      icons: { "16": "icons/quel_lexique.png" },
+      icons: { "16": "src/assets/icons/quel_lexique.png" },
     });
 
     // Item 2 : Ajouter le mot au(x) lexique(s) de l’utilisateur
@@ -39,7 +39,7 @@ async function createContextMenu() {
       id: "addToLexicon",
       title: "Ajouter ce mot à mes lexiques",
       contexts: ["selection"],
-      icons: { "16": "icons/ajout_lexique.png" },
+      icons: { "16": "src/assets/icons/ajout_lexique.png" },
     });
   }
 
@@ -55,7 +55,7 @@ async function createContextMenu() {
     id: "getDefinition",
     title: "Obtenir une définition",
     contexts: ["selection"],
-    icons: { "16": "icons/definition.png" },
+    icons: { "16": "src/assets/icons/definition.png" },
   });
 
   browser.contextMenus.create({
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 2d38fba..06f2530 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -264,14 +264,14 @@ async function showPicker(event, selectedText) {
     if (!Array.isArray(lexicons) || lexicons.length === 0) {
       picker.innerHTML = "<p>Aucun lexique trouvé.</p>";
     } else {
-      lexicons.forEach(lex => {
+      for (const lex of lexicons) {
         const id = lex.id;
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
         
         // Obtenir la couleur et créer le cercle
-        const color = getOrCreateLexiconColor(id);
+        const color = await getOrCreateLexiconColor(id);
         const circleIcon = createColorCircle(color, 32);
 
         // Crée un conteneur pour l'icône
@@ -309,7 +309,7 @@ async function showPicker(event, selectedText) {
             alert(`Erreur : ${error.message}`);
           }
         });
-      });
+      }
     }
 
     // Positionner et afficher le picker
@@ -323,3 +323,4 @@ async function showPicker(event, selectedText) {
   }
 }
 
+
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index e31a0dd..ef05621 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -204,11 +204,10 @@ async function fetchLexicons() {
 }
 
 /**
- * Affiche la liste des lexiques avec des checkboxes.
- * Les checkboxes servent ici à activer/désactiver le surlignage,
- * mais on va aussi s’en servir pour déterminer où ajouter le mot.
+ * Affiche la liste des lexiques avec des checkboxes dans la barre latérale.
+ * @param {Array} lexicons - Liste des lexiques à afficher.
  */
-function displayLexiconsWithCheckbox(lexicons) {
+async function displayLexiconsWithCheckbox(lexicons) {
   const lexiquesContainer = document.getElementById("lexiques");
   if (!lexiquesContainer) {
     console.warn("⚠️ Élément #lexiques introuvable.");
@@ -220,50 +219,49 @@ function displayLexiconsWithCheckbox(lexicons) {
     lexiquesContainer.textContent = "Aucun lexique disponible.";
     return;
   }
-
-  lexicons.forEach(({ lexiconName, lexiconId, active }) => {
+  
+  for (const { lexiconName, lexiconId, active } of lexicons) {
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
-
-    // Icône du lexique
-    const color = getOrCreateLexiconColor(lexiconId);
+    
+    // Obtenir la couleur associée de façon asynchrone
+    const color = await getOrCreateLexiconColor(lexiconId);
     const circleIcon = createColorCircle(color, 24);
+    
     const iconDiv = document.createElement("div");
     iconDiv.className = "lexique-icon";
     iconDiv.appendChild(circleIcon);
-
+    
     const labelSpan = document.createElement("span");
     labelSpan.className = "lexique-label";
     labelSpan.textContent = lexiconName;
-
-    // Conteneur pour la case à cocher avec tooltip
+    
+    // Conteneur pour la checkbox (avec tooltip)
     const checkboxContainer = document.createElement("label");
     checkboxContainer.className = "tooltip-container lexique-checkbox-container";
-
     const addCheckbox = document.createElement("input");
     addCheckbox.type = "checkbox";
     addCheckbox.className = "lexique-checkbox";
     addCheckbox.dataset.lexiconId = lexiconId;
-
     const checkboxTooltip = document.createElement("span");
     checkboxTooltip.className = "tooltip";
     checkboxTooltip.textContent = "Ajouter le mot à ce lexique";
-
-    // Conteneur pour le bouton de surlignage avec tooltip
+    checkboxContainer.appendChild(addCheckbox);
+    checkboxContainer.appendChild(checkboxTooltip);
+    
+    // Conteneur pour le bouton de surlignage (avec tooltip)
     const highlightButton = document.createElement("button");
     highlightButton.className = "tooltip-container lexique-highlight-toggle";
     highlightButton.dataset.lexiconId = lexiconId;
     highlightButton.dataset.active = active ? "true" : "false";
-
     const feutreIcon = document.createElement("img");
-    feutreIcon.src = "../assets/icons/feutre.png";
+    feutreIcon.src = "../assets/icons/feutre.png"; // Vérifiez le chemin relatif
     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";
-
+    
     // Gestion du clic pour activer/désactiver le surlignage
     highlightButton.addEventListener("click", async () => {
       let currentState = highlightButton.dataset.active === "true";
@@ -279,45 +277,43 @@ function displayLexiconsWithCheckbox(lexicons) {
         console.error("Erreur lors du toggle de surlignage pour le lexique", lexiconId, ":", error);
       }
     });
-
-    // Assemblage
+    
     highlightButton.appendChild(feutreIcon);
     highlightButton.appendChild(highlightTooltip);
-    checkboxContainer.appendChild(addCheckbox);
-    checkboxContainer.appendChild(checkboxTooltip);
-
+    
+    // Assemblage final
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
     lexiqueDiv.appendChild(checkboxContainer);
     lexiqueDiv.appendChild(highlightButton);
+    
     lexiquesContainer.appendChild(lexiqueDiv);
-  });
-
-  // Ajustement dynamique des tooltips
+  }
+  
+  // Ajustement dynamique des tooltips (après un court délai)
   setTimeout(() => {
     const menu = document.getElementById("menu");
+    if (!menu) return;
     const menuRect = menu.getBoundingClientRect();
     const containers = document.querySelectorAll('.tooltip-container');
-  
+    
     containers.forEach(container => {
       const tooltip = container.querySelector('.tooltip');
       if (!tooltip) return;
-
       tooltip.style.left = '50%';
       tooltip.style.transform = 'translateX(-50%) translateY(-5px)';
-  
+      
       const tooltipRect = tooltip.getBoundingClientRect();
       if (tooltipRect.left < menuRect.left) {
         const overflowLeft = menuRect.left - tooltipRect.left;
         tooltip.style.transform = `translateX(calc(-100% + ${overflowLeft}px)) translateY(-5px)`;
-      }
-      else if (tooltipRect.right > menuRect.right) {
+      } else if (tooltipRect.right > menuRect.right) {
         const overflowRight = tooltipRect.right - menuRect.right;
         tooltip.style.transform = `translateX(calc(-100% - ${overflowRight}px)) translateY(-5px)`;
       }
     });
   }, 100);
-}  
+}
 
 
 
-- 
GitLab


From 99ef6749a83c75c4a2a9d2211919c727fd1918fc Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Wed, 12 Feb 2025 11:33:03 +0100
Subject: [PATCH 18/23] Correction beugs

---
 manifest.json                |  2 +-
 src/assets/lexicon_icon.js   | 29 +++++++++++++++++++----------
 src/background/background.js | 10 +++++++++-
 src/sidebar/sidebar.js       |  2 +-
 4 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/manifest.json b/manifest.json
index a74107e..08791cc 100644
--- a/manifest.json
+++ b/manifest.json
@@ -60,7 +60,7 @@
         "src/sidebar/sidebar.js",
         "src/context_menu/custom_context_menu.js"],
       "css": ["src/context_menu/custom_context_menu.css"],
-      "run_at": "document_end"
+      "run_at": "document_idle"
     }
   ],
 
diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 5fc780a..9228f82 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -1,16 +1,25 @@
 console.log("lexicon_icon.js chargé");
 
 /**
- * Génère une couleur hexadécimale aléatoire (#RRGGBB).
- * @returns {string} Une couleur hexadécimale, ex: "#A1B2C3".
+ * Sélectionne aléatoirement une couleur dans une palette prédéfinie.
+ * @returns {string} Une couleur au format hexadécimal ou HSL.
  */
 function generateRandomColor() {
-  const letters = '0123456789ABCDEF';
-  let color = '#';
-  for (let i = 0; i < 6; i++) {
-    color += letters[Math.floor(Math.random() * 16)];
-  }
-  return color;
+  const palette = [
+    "#6e76c7", 
+    "#00a0bd", 
+    "#96cd95", 
+    "#ffeac2", 
+    "#fff6ff", 
+    "#e67e22",
+    "#20bad8",
+    "#f290e7",
+    "#f4ab9d",
+    "#f1e87a",
+    "#84e8e6"
+  ];
+  const index = Math.floor(Math.random() * palette.length);
+  return palette[index];
 }
 
 /**
@@ -18,10 +27,10 @@ function generateRandomColor() {
  * @param {string|number} lexiconId - L'identifiant du lexique.
  * @returns {Promise<string>} La couleur associée au lexique.
  */
-async function getOrCreateLexiconColor(lexiconId) {
+async function getOrCreateLexiconColor(lexiconId, forceReset = false) {
   // Récupère la correspondance stockée dans storage
   let { lexiconColors } = await browser.storage.local.get("lexiconColors");
-  if (!lexiconColors) {
+  if (!lexiconColors || forceReset) {
     lexiconColors = {};
   }
   // Si aucune couleur n'est associée à ce lexiconId, on la génère et on la sauvegarde
diff --git a/src/background/background.js b/src/background/background.js
index e1f36c5..6203313 100644
--- a/src/background/background.js
+++ b/src/background/background.js
@@ -88,11 +88,18 @@ async function actuallyOpenLoginPage() {
   browser.runtime.sendMessage({ action: "authStatusChanged", isLoggedIn: false });
 }
 
-// Déconnecte l'utilisateur (sans notification)
+// 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);
+  }
   setTimeout(async () => {
     await refreshAllUI();
   }, 500);
@@ -135,6 +142,7 @@ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => {
       const isConnected = await isUserConnected();
       if (isConnected) {
         await disconnectFromLexicalDB();
+        await browser.storage.local.remove("lexiconColors");
       } else {
         actuallyOpenLoginPage();
       }
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index ef05621..5d619b5 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -533,7 +533,7 @@ document.addEventListener("DOMContentLoaded", async () => {
     authButton.addEventListener("click", handleAuthButtonClick);
   }
 
-  const chercherDefButton = document.getElementById("chercherDef");
+  const chercherDefButton = document.querySelector("#chercherDef");
   if (chercherDefButton) {
     chercherDefButton.addEventListener("click", async () => {
       openBlock("definitionContent");
-- 
GitLab


From 4074ed53d806830c736a1b9d8b1a84980171ef8d Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Wed, 12 Feb 2025 13:18:35 +0100
Subject: [PATCH 19/23] Ouverture auto bloc Lexiques menu contextuel perso
 bouton ajout

---
 src/context_menu/custom_context_menu.js | 56 +++++++++++++++++++++++--
 src/sidebar/sidebar.js                  |  4 ++
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 06f2530..2e0ea97 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -97,7 +97,8 @@ function setupWhiteBoxActions() {
     console.log("🔍 Bouton Ajouter au lexique cliqué avec le mot :", selectedText);
     if (!selectedText) return;
     if (authToken) {
-      await showPicker(e, selectedText);
+      browser.runtime.sendMessage({ action: "openLexiconBlock" });
+      showPicker(e, selectedText);
     } else {
       alert("Vous devez être connecté pour ajouter un mot.");
     }
@@ -234,20 +235,26 @@ function createPicker() {
   if (!picker) {
     picker = document.createElement("div");
     picker.id = "lexiconPicker";
-    // Styles pour le picker
     picker.style.position = "absolute";
     picker.style.zIndex = "10000";
     picker.style.backgroundColor = "rgba(255, 255, 255, 0.95)";
     picker.style.border = "1px solid #ccc";
-    picker.style.padding = "10px";
+    picker.style.padding = "5px";
     picker.style.borderRadius = "4px";
     picker.style.boxShadow = "0 2px 10px rgba(0,0,0,0.3)";
     picker.style.display = "none";
+    
+    picker.style.display = "flex";
+    picker.style.flexWrap = "wrap"; 
+    picker.style.gap = "10px"; 
+    picker.style.alignItems = "center"; 
+
     document.body.appendChild(picker);
   }
   return picker;
 }
 
+
 /**
  * Affiche le picker pour choisir le lexique dans lequel ajouter le mot.
  * Pour chaque lexique, vérifie si le mot existe déjà dans ce lexique en appelant fetchLexiconDefinitions.
@@ -278,9 +285,14 @@ async function showPicker(event, selectedText) {
         const iconContainer = document.createElement("div");
         iconContainer.className = "lexicon-option";
         iconContainer.dataset.lexiconId = id;
-        iconContainer.style.margin = "5px";
+        iconContainer.style.margin = "2px";
         iconContainer.style.cursor = "pointer";
         iconContainer.title = name;
+        iconContainer.style.display = "inline-flex";
+        iconContainer.style.flexDirection = "row"; // Assurez-vous que c'est horizontal
+        iconContainer.style.alignItems = "center"; // Alignement centré
+        iconContainer.style.justifyContent = "center";
+
 
         // Ajoute le cercle coloré au conteneur
         iconContainer.appendChild(circleIcon);
@@ -323,4 +335,40 @@ async function showPicker(event, selectedText) {
   }
 }
 
+function hideLexiconPicker() {
+  const picker = document.getElementById("lexiconPicker");
+  if (picker) {
+    picker.style.display = "none";
+  }
+}
+
 
+document.addEventListener("mouseup", (event) => {
+  const whiteBox = document.getElementById(WHITE_BOX_ID);
+  const picker = document.getElementById("lexiconPicker");
+
+  if (picker && picker.style.display === "block" && !picker.contains(event.target)) {
+    hideLexiconPicker();
+  }
+
+  // Vérifier si le clic est à l'extérieur des éléments
+  if (
+    whiteBox && whiteBox.style.display === "block" && 
+    !whiteBox.contains(event.target) &&
+    (!picker || !picker.contains(event.target))
+  ) {
+    hideWhiteBox();
+    if (picker) picker.style.display = "none";
+  }
+
+  // Vérifier s'il y a du texte sélectionné
+  const selectedText = window.getSelection().toString().trim();
+  if (selectedText) {
+    console.log("Texte sélectionné :", selectedText);
+    showWhiteBox(event, selectedText);
+    browser.runtime.sendMessage({
+      action: "mot_selectionne",
+      selectedText,
+    });
+  }
+});
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index 5d619b5..0668c86 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -509,6 +509,10 @@ browser.runtime.onMessage.addListener(async (message) => {
     case "addToLexicon":
       handleAddWordClick();
       break;
+    
+    case "openLexiconBlock":
+      openBlock("menuContent");
+      break;
       
     case "toggleAuth":
       break;
-- 
GitLab


From 6cf36ddf183699b7ed90bce32b926eafa2c84240 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Wed, 12 Feb 2025 15:22:10 +0100
Subject: [PATCH 20/23] =?UTF-8?q?Liens=20fonctions=20ajout=20mot=20menu=20?=
 =?UTF-8?q?contextuel/barre=20lat=C3=A9rale?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/context_menu/custom_context_menu.js | 133 ++++++++++++++++++------
 src/sidebar/sidebar.js                  |   7 ++
 2 files changed, 111 insertions(+), 29 deletions(-)

diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 2e0ea97..b9f6617 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -262,12 +262,14 @@ function createPicker() {
  */
 async function showPicker(event, selectedText) {
   console.log("showPicker appelé avec", event, selectedText);
-  const picker = createPicker(); // supposez que createPicker est défini ailleurs dans ce fichier
+  const picker = createPicker();
   picker.innerHTML = ""; // Vider le picker
+  const selectedLexicons = new Set(); // Stocke les lexiques sélectionnés
 
   try {
     const lexicons = await getLexicons(authToken, "fr");
     console.log("Lexicons récupérés :", lexicons);
+
     if (!Array.isArray(lexicons) || lexicons.length === 0) {
       picker.innerHTML = "<p>Aucun lexique trouvé.</p>";
     } else {
@@ -276,52 +278,121 @@ async function showPicker(event, selectedText) {
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
-        
+
         // Obtenir la couleur et créer le cercle
         const color = await getOrCreateLexiconColor(id);
         const circleIcon = createColorCircle(color, 32);
 
-        // Crée un conteneur pour l'icône
+        // Créer un conteneur pour l'icône
         const iconContainer = document.createElement("div");
         iconContainer.className = "lexicon-option";
         iconContainer.dataset.lexiconId = id;
-        iconContainer.style.margin = "2px";
+        iconContainer.style.margin = "5px";
         iconContainer.style.cursor = "pointer";
         iconContainer.title = name;
         iconContainer.style.display = "inline-flex";
-        iconContainer.style.flexDirection = "row"; // Assurez-vous que c'est horizontal
-        iconContainer.style.alignItems = "center"; // Alignement centré
+        iconContainer.style.flexDirection = "row";
+        iconContainer.style.alignItems = "center";
         iconContainer.style.justifyContent = "center";
-
+        iconContainer.style.border = "2px solid transparent"; 
 
         // Ajoute le cercle coloré au conteneur
         iconContainer.appendChild(circleIcon);
         picker.appendChild(iconContainer);
 
-        // Écouteur de clic pour ajouter le mot au lexique sélectionné
-        iconContainer.addEventListener("click", async () => {
-          console.log(`Tentative d'ajout du mot "${selectedText}" au lexique ${id} (${name})`);
-          try {
-            let definitions = [];
-            try {
-              definitions = await fetchLexiconDefinitions(selectedText);
-            } catch (err) {
-              console.error("Erreur lors de la récupération des définitions :", err);
-            }
-            const exists = Array.isArray(definitions) && definitions.some(def => def.lexiconId === id);
-            if (exists) {
-              alert(`Le mot "${selectedText}" existe déjà dans le lexique ${name}.`);
-            } else {
-              await window.AddWord(authToken, selectedText, [id], false);
-              alert(`Le mot "${selectedText}" a été ajouté dans le lexique ${name}.`);
-            }
-            picker.style.display = "none";
-          } catch (error) {
-            console.error("Erreur lors de l'ajout du mot :", error);
-            alert(`Erreur : ${error.message}`);
+        // Écouteur de clic pour sélectionner/désélectionner le lexique
+        iconContainer.addEventListener("click", () => {
+          if (selectedLexicons.has(id)) {
+            selectedLexicons.delete(id);
+            iconContainer.style.border = "2px solid transparent"; 
+          } else {
+            selectedLexicons.add(id);
+            iconContainer.style.border = "2px solid black";
           }
         });
       }
+
+      // Ajouter un bouton de validation
+      const confirmButton = document.createElement("button");
+      confirmButton.textContent = "Ajouter aux lexiques sélectionnés";
+      confirmButton.style.fontStyle = "italic";
+      confirmButton.style.fontSize = "8px";
+      confirmButton.style.marginTop = "10px";
+      confirmButton.style.padding = "5px 10px";
+      confirmButton.style.cursor = "pointer";
+      confirmButton.style.border = "none";
+      confirmButton.style.borderRadius = "4px";
+      confirmButton.style.backgroundColor = "#6e76c7";
+      confirmButton.style.color = "white";
+
+      confirmButton.addEventListener("click", async () => {
+        if (selectedLexicons.size === 0) {
+          alert("Veuillez sélectionner au moins un lexique.");
+          return;
+        }
+
+        console.log(`🔍 Vérification si le mot "${selectedText}" existe déjà dans les lexiques sélectionnés...`);
+
+        let definitions = [];
+        try {
+          definitions = await fetchLexiconDefinitions(selectedText);
+        } catch (error) {
+          console.error("❌ Erreur lors de la récupération des définitions :", error);
+        }
+
+        const existingLexiconIds = new Set();
+        if (Array.isArray(definitions)) {
+          for (const def of definitions) {
+            if (selectedLexicons.has(def.lexiconId)) {
+              existingLexiconIds.add(def.lexiconId);
+            }
+          }
+        }
+
+        // Affichage des lexiques où le mot existe déjà
+        if (existingLexiconIds.size > 0) {
+          alert(`⚠️ Le mot "${selectedText}" existe déjà dans les lexiques suivants : ${Array.from(existingLexiconIds).join(", ")}`);
+        }
+
+        // Filtrer les lexiques où le mot n'existe pas encore
+        const lexiconsToAdd = [...selectedLexicons].filter(id => !existingLexiconIds.has(id));
+
+        if (lexiconsToAdd.length === 0) {
+          alert(`✅ Le mot "${selectedText}" est déjà présent dans tous les lexiques sélectionnés.`);
+          return;
+        }
+
+        // Envoi de la requête d'ajout
+        try {
+          console.log(`📡 Ajout du mot "${selectedText}" dans les lexiques :`, lexiconsToAdd);
+          const result = await AddWord(authToken, selectedText, lexiconsToAdd, false);
+          console.log("✅ Réponse API :", result);
+
+          // Rafraîchir l'UI après l'ajout
+          await new Promise(resolve => setTimeout(resolve, 300));
+          browser.runtime.sendMessage({ action: "refreshUI" });
+
+          // Affichage du message de confirmation dans le picker
+          picker.innerHTML = `<p style="color: green;">✅ Mot ajouté avec succès dans : ${lexiconsToAdd.join(", ")}.</p>`;
+          setTimeout(() => picker.style.display = "none", 2000);
+          browser.runtime.sendMessage({
+            action: "addWordResult",
+            lexicons:`✅ Mot ajouté avec succès dans : ${lexiconsToAdd.join(", ")}.`
+          });
+        } catch (error) {
+          console.error("❌ Erreur lors de l'ajout du mot :", error);
+
+          // Affichage du message d'erreur dans le picker
+          picker.innerHTML = `<p style="color: red;">❌ Erreur : ${error.message}</p>`;
+          setTimeout(() => picker.style.display = "none", 3000);
+          browser.runtime.sendMessage({
+            action: "addWordResult",
+            lexicons: `❌ Erreur lors de l'ajout du mot : ${error.message}`
+          });
+        }
+      });
+
+      picker.appendChild(confirmButton);
     }
 
     // Positionner et afficher le picker
@@ -329,12 +400,16 @@ async function showPicker(event, selectedText) {
     picker.style.top = event.pageY + "px";
     picker.style.display = "block";
   } catch (error) {
-    console.error("Erreur lors de la récupération des lexiques :", error);
+    console.error("❌ Erreur lors de la récupération des lexiques :", error);
     picker.innerHTML = "<p>Erreur lors du chargement des lexiques.</p>";
     picker.style.display = "block";
   }
 }
 
+
+
+
+
 function hideLexiconPicker() {
   const picker = document.getElementById("lexiconPicker");
   if (picker) {
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index 0668c86..c937cc6 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -506,6 +506,13 @@ browser.runtime.onMessage.addListener(async (message) => {
       window.displayLexiconResults(message.lexicons);
       break;
     
+    case "addWordResult":
+      const lexiconResultElement = document.getElementById("lexiconResult");
+      if (lexiconResultElement) {
+        lexiconResultElement.innerHTML = message.lexicons;
+      }
+      break;
+
     case "addToLexicon":
       handleAddWordClick();
       break;
-- 
GitLab


From 34c86229ee6d4ac7a0ee10e14b30e34af7c205ce Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Thu, 13 Feb 2025 11:21:18 +0100
Subject: [PATCH 21/23] Messages confirmation/erreur ajout mot menu contextuel

---
 src/assets/lexicon_icon.js               |   3 +-
 src/context_menu/custom_context_menu.css | 233 +++++++++++++++--------
 src/context_menu/custom_context_menu.js  |  99 ++++------
 3 files changed, 193 insertions(+), 142 deletions(-)

diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 9228f82..394d73d 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -49,11 +49,12 @@ async function getOrCreateLexiconColor(lexiconId, forceReset = false) {
  */
 function createColorCircle(color, size = 32) {
   const circle = document.createElement("div");
+  circle.className = "color-circle";
   circle.style.width = `${size}px`;
   circle.style.height = `${size}px`;
   circle.style.borderRadius = "50%";
   circle.style.backgroundColor = color;
-  circle.style.border = "1px solid black"; // Optionnel
+  circle.style.border = "1px solid black";
   return circle;
 }
 
diff --git a/src/context_menu/custom_context_menu.css b/src/context_menu/custom_context_menu.css
index 30f66df..7bc2f23 100644
--- a/src/context_menu/custom_context_menu.css
+++ b/src/context_menu/custom_context_menu.css
@@ -1,81 +1,156 @@
 /* === Conteneur principal du menu contextuel === */
 #whiteBox {
-    position: absolute; 
-    display: none; 
-    min-width: 50px;         
-    max-width: 300px;         
-    background-color: white; 
-    color: #323046;           
-    border: 2px solid #323046;
-    border-radius: 10px;
-    padding: 10px;
-    box-shadow: 0 4px 12px rgba(0,0,0,0.2);
-    font-family: "Helvetica", sans-serif; 
-    z-index: 10000;
-  }
-  
-  /* === Titre/texte indiquant le mot sélectionné === */
-  #whiteBox #selectedWord {
-    margin: 0;
-    margin-bottom: 8px;
-    font-size: 14px;
-    line-height: 1.3;
-    color: #323046;  
-    font-weight: bold;
-    text-align: center; 
-  }
-  
-  /* === Conteneur des icônes === */
-  #whiteBox .icon-container {
-    position: relative;
-    display: flex;
-    flex-direction: column; 
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-    margin: 0;
-    padding: 0;
-  }
-  
-  #whiteBox .icon-container:hover {
-    background-color: rgba(255, 255, 255, 0.1); 
-    border-radius: 6px;
-  }
-  
-  /* === Les icônes elles-mêmes === */
-  #whiteBox .icon {
-    width: 40px;       
-    height: 40px;
-    transition: transform 0.2s ease;
-    margin : 0 auto;
-    display: block;
-  }
-  
-  #whiteBox .icon:hover {
-    transform: scale(1.15); 
-  }
-  
-  /* === Message (tooltips) === */
-  #whiteBox .tooltip {
-    visibility: hidden;
-    background-color: #333;
-    color: #fff;
-    text-align: center;
-    padding: 6px;
-    border-radius: 5px;
-    position: absolute;
-    bottom: -34px; 
-    left: 50%;
-    transform: translateX(-50%);
-    white-space: nowrap;
-    font-size: 12px;
-    opacity: 0;
-    transition: opacity 0.2s ease, visibility 0.2s ease;
-    z-index: 1000;
-  }
-  
-  #whiteBox .icon-container:hover .tooltip {
-    visibility: visible;
-    opacity: 1;
-  }
-  
\ No newline at end of file
+  position: absolute; 
+  display: none; 
+  min-width: 50px;         
+  max-width: 300px;         
+  background-color: white; 
+  color: #323046;           
+  border: 2px solid #323046;
+  border-radius: 10px;
+  padding: 10px;
+  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
+  font-family: "Helvetica", sans-serif; 
+  z-index: 10000;
+}
+
+/* === Titre/texte indiquant le mot sélectionné === */
+#whiteBox #selectedWord {
+  margin: 0;
+  margin-bottom: 8px;
+  font-size: 14px;
+  line-height: 1.3;
+  color: #323046;  
+  font-weight: bold;
+  text-align: center; 
+}
+
+/* === Conteneur des icônes === */
+#whiteBox .icon-container {
+  position: relative;
+  display: flex;
+  flex-direction: column; 
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+  margin: 0;
+  padding: 0;
+}
+
+#whiteBox .icon-container:hover {
+  background-color: rgba(255, 255, 255, 0.1); 
+  border-radius: 6px;
+}
+
+/* === Les icônes elles-mêmes === */
+#whiteBox .icon {
+  width: 40px;       
+  height: 40px;
+  transition: transform 0.2s ease;
+  margin : 0 auto;
+  display: block;
+}
+
+#whiteBox .icon:hover {
+  transform: scale(1.15); 
+}
+
+/* === Message (tooltips) === */
+#whiteBox .tooltip {
+  visibility: hidden;
+  background-color: #333;
+  color: #fff;
+  text-align: center;
+  padding: 6px;
+  border-radius: 5px;
+  position: absolute;
+  bottom: -34px; 
+  left: 50%;
+  transform: translateX(-50%);
+  white-space: nowrap;
+  font-size: 12px;
+  opacity: 0;
+  transition: opacity 0.2s ease, visibility 0.2s ease;
+  z-index: 1000;
+}
+
+#whiteBox .icon-container:hover .tooltip {
+  visibility: visible;
+  opacity: 1;
+}
+
+/* === Style global du lexiconPicker === */
+#lexiconPicker {
+  position: absolute;
+  z-index: 10000;
+  background-color: rgba(255, 255, 255, 0.98);
+  border: 1px solid #ddd;
+  padding: 4px;
+  border-radius: 8px;
+  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+  width: 150px; 
+  font-family: Arial, sans-serif;
+  font-size: 10px;
+  display: flex !important;
+  flex-direction: row !important;
+  flex-wrap: wrap !important;    
+  align-items: center;
+  justify-content: center;
+  gap: 2px;
+}
+
+/* Style pour les icônes de lexique */
+#lexiconPicker .lexicon-option {
+  cursor: pointer;
+  display: inline-flex !important;
+  flex-direction: row !important;
+  align-items: center;
+  justify-content: center;
+  border: 2px solid transparent;
+  border-radius: 50%;
+  width: 40px;
+  height: 40px;
+  transition: border 0.2s ease;
+  flex: 0 0 auto;
+}
+
+/* Effet au survol pour les icônes */
+#lexiconPicker .lexicon-option:hover {
+  border: 2px solid #6e76c7;
+}
+
+/* Classe pour indiquer qu'une icône est sélectionnée */
+#lexiconPicker .lexicon-option.selected {
+  border: 2px solid #323046;
+}
+
+/* Style pour le cercle de couleur (icône interne) */
+#lexiconPicker .color-circle {
+  width: 28px;  /* ajustez la taille si besoin */
+  height: 28px;
+  border-radius: 50%;
+  display: inline-block;
+  /* La couleur de fond sera définie dynamiquement via JS */
+  border: 1px solid black; /* optionnel */
+}
+
+/* Style pour le bouton de confirmation */
+#lexiconPicker button.confirmButton {
+  font-style: italic;
+  font-size: 10px;
+  padding: 6px 10px;
+  cursor: pointer;
+  border: none;
+  border-radius: 4px;
+  background-color: #323046;
+  color: white;
+  flex-basis: 100%; /* force le bouton à occuper toute la largeur et à passer à la ligne */
+  margin-top: 8px;
+}
+
+#lexiconPicker p {
+  font-size: 12px;
+  font-weight: bold;
+  text-align: center;
+}
+
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index b9f6617..91e117b 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -237,93 +237,80 @@ function createPicker() {
     picker.id = "lexiconPicker";
     picker.style.position = "absolute";
     picker.style.zIndex = "10000";
-    picker.style.backgroundColor = "rgba(255, 255, 255, 0.95)";
-    picker.style.border = "1px solid #ccc";
-    picker.style.padding = "5px";
-    picker.style.borderRadius = "4px";
-    picker.style.boxShadow = "0 2px 10px rgba(0,0,0,0.3)";
-    picker.style.display = "none";
-    
+    picker.style.backgroundColor = "rgba(255, 255, 255, 0.98)";
+    picker.style.border = "1px solid #ddd";
+    picker.style.padding = "8px";
+    picker.style.borderRadius = "8px";
+    picker.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)";
+    picker.style.width = "220px"; // largeur adaptée pour afficher les icônes sur une ligne
+    picker.style.fontFamily = "Arial, sans-serif";
+    picker.style.fontSize = "10px";
+    // Définir le picker en flex avec direction horizontale
     picker.style.display = "flex";
-    picker.style.flexWrap = "wrap"; 
-    picker.style.gap = "10px"; 
-    picker.style.alignItems = "center"; 
-
+    picker.style.flexDirection = "row"; // IMPORTANT : aligne les éléments en ligne
+    picker.style.flexWrap = "wrap";      // autorise le retour à la ligne si nécessaire
+    picker.style.alignItems = "center";
+    picker.style.justifyContent = "center";
+    picker.style.gap = "5px";
     document.body.appendChild(picker);
   }
   return picker;
 }
 
-
 /**
  * Affiche le picker pour choisir le lexique dans lequel ajouter le mot.
- * Pour chaque lexique, vérifie si le mot existe déjà dans ce lexique en appelant fetchLexiconDefinitions.
- * S'il n'existe pas, appelle window.AddWord pour l'ajouter.
  */
 async function showPicker(event, selectedText) {
-  console.log("showPicker appelé avec", event, selectedText);
-  const picker = createPicker();
-  picker.innerHTML = ""; // Vider le picker
-  const selectedLexicons = new Set(); // Stocke les lexiques sélectionnés
+  let picker = document.getElementById("lexiconPicker");
+  if (!picker) {
+    picker = document.createElement("div");
+    picker.id = "lexiconPicker";
+    document.body.appendChild(picker);
+  }
+  picker.innerHTML = ""; 
+  
+  const selectedLexicons = new Set();
 
   try {
     const lexicons = await getLexicons(authToken, "fr");
     console.log("Lexicons récupérés :", lexicons);
 
     if (!Array.isArray(lexicons) || lexicons.length === 0) {
-      picker.innerHTML = "<p>Aucun lexique trouvé.</p>";
+      picker.innerHTML = "<p style='color:#333;'>Aucun lexique trouvé.</p>";
     } else {
+      // Ajout des icônes directement dans le picker
       for (const lex of lexicons) {
         const id = lex.id;
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
 
-        // Obtenir la couleur et créer le cercle
+        // Obtenir la couleur et créer un cercle (l'icône)
         const color = await getOrCreateLexiconColor(id);
-        const circleIcon = createColorCircle(color, 32);
+        const circleIcon = createColorCircle(color, 28); 
 
-        // Créer un conteneur pour l'icône
+        // Création du conteneur pour l'icône
         const iconContainer = document.createElement("div");
         iconContainer.className = "lexicon-option";
         iconContainer.dataset.lexiconId = id;
-        iconContainer.style.margin = "5px";
-        iconContainer.style.cursor = "pointer";
         iconContainer.title = name;
-        iconContainer.style.display = "inline-flex";
-        iconContainer.style.flexDirection = "row";
-        iconContainer.style.alignItems = "center";
-        iconContainer.style.justifyContent = "center";
-        iconContainer.style.border = "2px solid transparent"; 
-
-        // Ajoute le cercle coloré au conteneur
-        iconContainer.appendChild(circleIcon);
-        picker.appendChild(iconContainer);
-
-        // Écouteur de clic pour sélectionner/désélectionner le lexique
         iconContainer.addEventListener("click", () => {
           if (selectedLexicons.has(id)) {
             selectedLexicons.delete(id);
-            iconContainer.style.border = "2px solid transparent"; 
+            iconContainer.classList.remove("selected");
           } else {
             selectedLexicons.add(id);
-            iconContainer.style.border = "2px solid black";
+            iconContainer.classList.add("selected");
           }
         });
+        iconContainer.appendChild(circleIcon);
+        picker.appendChild(iconContainer);
       }
 
-      // Ajouter un bouton de validation
+      // Création du bouton de validation qui passera sur une nouvelle ligne
       const confirmButton = document.createElement("button");
-      confirmButton.textContent = "Ajouter aux lexiques sélectionnés";
-      confirmButton.style.fontStyle = "italic";
-      confirmButton.style.fontSize = "8px";
-      confirmButton.style.marginTop = "10px";
-      confirmButton.style.padding = "5px 10px";
-      confirmButton.style.cursor = "pointer";
-      confirmButton.style.border = "none";
-      confirmButton.style.borderRadius = "4px";
-      confirmButton.style.backgroundColor = "#6e76c7";
-      confirmButton.style.color = "white";
+      confirmButton.className = "confirmButton";
+      confirmButton.textContent = "Ajouter le mot";
 
       confirmButton.addEventListener("click", async () => {
         if (selectedLexicons.size === 0) {
@@ -349,40 +336,32 @@ async function showPicker(event, selectedText) {
           }
         }
 
-        // Affichage des lexiques où le mot existe déjà
         if (existingLexiconIds.size > 0) {
           alert(`⚠️ Le mot "${selectedText}" existe déjà dans les lexiques suivants : ${Array.from(existingLexiconIds).join(", ")}`);
         }
 
-        // Filtrer les lexiques où le mot n'existe pas encore
         const lexiconsToAdd = [...selectedLexicons].filter(id => !existingLexiconIds.has(id));
-
         if (lexiconsToAdd.length === 0) {
           alert(`✅ Le mot "${selectedText}" est déjà présent dans tous les lexiques sélectionnés.`);
           return;
         }
 
-        // Envoi de la requête d'ajout
         try {
           console.log(`📡 Ajout du mot "${selectedText}" dans les lexiques :`, lexiconsToAdd);
           const result = await AddWord(authToken, selectedText, lexiconsToAdd, false);
           console.log("✅ Réponse API :", result);
 
-          // Rafraîchir l'UI après l'ajout
           await new Promise(resolve => setTimeout(resolve, 300));
           browser.runtime.sendMessage({ action: "refreshUI" });
 
-          // Affichage du message de confirmation dans le picker
           picker.innerHTML = `<p style="color: green;">✅ Mot ajouté avec succès dans : ${lexiconsToAdd.join(", ")}.</p>`;
           setTimeout(() => picker.style.display = "none", 2000);
           browser.runtime.sendMessage({
             action: "addWordResult",
-            lexicons:`✅ Mot ajouté avec succès dans : ${lexiconsToAdd.join(", ")}.`
+            lexicons: `✅ Mot ajouté avec succès dans : ${lexiconsToAdd.join(", ")}.`
           });
         } catch (error) {
           console.error("❌ Erreur lors de l'ajout du mot :", error);
-
-          // Affichage du message d'erreur dans le picker
           picker.innerHTML = `<p style="color: red;">❌ Erreur : ${error.message}</p>`;
           setTimeout(() => picker.style.display = "none", 3000);
           browser.runtime.sendMessage({
@@ -401,15 +380,11 @@ async function showPicker(event, selectedText) {
     picker.style.display = "block";
   } catch (error) {
     console.error("❌ Erreur lors de la récupération des lexiques :", error);
-    picker.innerHTML = "<p>Erreur lors du chargement des lexiques.</p>";
+    picker.innerHTML = "<p style='color:#333;'>Erreur lors du chargement des lexiques.</p>";
     picker.style.display = "block";
   }
 }
 
-
-
-
-
 function hideLexiconPicker() {
   const picker = document.getElementById("lexiconPicker");
   if (picker) {
-- 
GitLab


From 25f0c7137219e4de46b82c06c5c17ea3c07ed9c9 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Thu, 13 Feb 2025 17:09:34 +0100
Subject: [PATCH 22/23] =?UTF-8?q?Changement=20couleurs=20ic=C3=B4nes=20lex?=
 =?UTF-8?q?iques?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/assets/lexicon_icon.js               | 29 ++++++++++++--------
 src/context_menu/custom_context_menu.css | 11 ++++----
 src/context_menu/custom_context_menu.js  | 34 ++++++++++++------------
 3 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 394d73d..7b843b8 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -6,17 +6,24 @@ console.log("lexicon_icon.js chargé");
  */
 function generateRandomColor() {
   const palette = [
-    "#6e76c7", 
-    "#00a0bd", 
-    "#96cd95", 
-    "#ffeac2", 
-    "#fff6ff", 
-    "#e67e22",
-    "#20bad8",
-    "#f290e7",
-    "#f4ab9d",
-    "#f1e87a",
-    "#84e8e6"
+    "#231942",
+    "#5E548E",
+    "#9F86C0",
+    "#BE95C4",
+    "#E0B1CB",
+    "#b7094c",
+    "#a01a58",
+    "#892b64",
+    "#723c70",
+    "#5b4d7c",
+    "#455e89",
+    "#2e6f95",
+    "#1780a1",
+    "#0091ad",
+    "#30343f",
+    "#e4d9ff",
+    "#273469",
+    "#1e2749"
   ];
   const index = Math.floor(Math.random() * palette.length);
   return palette[index];
diff --git a/src/context_menu/custom_context_menu.css b/src/context_menu/custom_context_menu.css
index 7bc2f23..f763805 100644
--- a/src/context_menu/custom_context_menu.css
+++ b/src/context_menu/custom_context_menu.css
@@ -91,7 +91,7 @@
   width: 150px; 
   font-family: Arial, sans-serif;
   font-size: 10px;
-  display: flex !important;
+  display: flex;
   flex-direction: row !important;
   flex-wrap: wrap !important;    
   align-items: center;
@@ -126,12 +126,11 @@
 
 /* Style pour le cercle de couleur (icône interne) */
 #lexiconPicker .color-circle {
-  width: 28px;  /* ajustez la taille si besoin */
+  width: 28px;  
   height: 28px;
   border-radius: 50%;
   display: inline-block;
-  /* La couleur de fond sera définie dynamiquement via JS */
-  border: 1px solid black; /* optionnel */
+  border: 1px solid black;
 }
 
 /* Style pour le bouton de confirmation */
@@ -141,10 +140,12 @@
   padding: 6px 10px;
   cursor: pointer;
   border: none;
+  align-items: center;
+  text-align: center;
   border-radius: 4px;
   background-color: #323046;
   color: white;
-  flex-basis: 100%; /* force le bouton à occuper toute la largeur et à passer à la ligne */
+  flex-basis: 100%; 
   margin-top: 8px;
 }
 
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index 91e117b..c37004a 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -242,21 +242,26 @@ function createPicker() {
     picker.style.padding = "8px";
     picker.style.borderRadius = "8px";
     picker.style.boxShadow = "0 4px 8px rgba(0, 0, 0, 0.1)";
-    picker.style.width = "220px"; // largeur adaptée pour afficher les icônes sur une ligne
+    picker.style.width = "220px";
     picker.style.fontFamily = "Arial, sans-serif";
     picker.style.fontSize = "10px";
-    // Définir le picker en flex avec direction horizontale
     picker.style.display = "flex";
-    picker.style.flexDirection = "row"; // IMPORTANT : aligne les éléments en ligne
-    picker.style.flexWrap = "wrap";      // autorise le retour à la ligne si nécessaire
+    picker.style.flexDirection = "row";
+    picker.style.flexWrap = "wrap";
     picker.style.alignItems = "center";
     picker.style.justifyContent = "center";
     picker.style.gap = "5px";
+
+    picker.addEventListener("mouseup", (e) => {
+      e.stopPropagation();
+    });
+
     document.body.appendChild(picker);
   }
   return picker;
 }
 
+
 /**
  * Affiche le picker pour choisir le lexique dans lequel ajouter le mot.
  */
@@ -377,7 +382,7 @@ async function showPicker(event, selectedText) {
     // Positionner et afficher le picker
     picker.style.left = event.pageX + "px";
     picker.style.top = event.pageY + "px";
-    picker.style.display = "block";
+    picker.style.display = "flex";
   } catch (error) {
     console.error("❌ Erreur lors de la récupération des lexiques :", error);
     picker.innerHTML = "<p style='color:#333;'>Erreur lors du chargement des lexiques.</p>";
@@ -392,23 +397,18 @@ function hideLexiconPicker() {
   }
 }
 
-
 document.addEventListener("mouseup", (event) => {
   const whiteBox = document.getElementById(WHITE_BOX_ID);
   const picker = document.getElementById("lexiconPicker");
 
-  if (picker && picker.style.display === "block" && !picker.contains(event.target)) {
-    hideLexiconPicker();
-  }
-
-  // Vérifier si le clic est à l'extérieur des éléments
-  if (
-    whiteBox && whiteBox.style.display === "block" && 
-    !whiteBox.contains(event.target) &&
-    (!picker || !picker.contains(event.target))
-  ) {
+  // Masquer whiteBox si le clic est en dehors
+  if (whiteBox && !whiteBox.contains(event.target)) {
     hideWhiteBox();
-    if (picker) picker.style.display = "none";
+  }
+  
+  // Masquer picker si le clic est en dehors
+  if (picker && !picker.contains(event.target)) {
+    hideLexiconPicker();
   }
 
   // Vérifier s'il y a du texte sélectionné
-- 
GitLab


From fb3a0c195407966c3465faf8547c362484161108 Mon Sep 17 00:00:00 2001
From: Lucie Bader <167515375+Lucie-Bdr@users.noreply.github.com>
Date: Thu, 13 Feb 2025 17:29:07 +0100
Subject: [PATCH 23/23] Correction code

---
 src/assets/lexicon_icon.js              |  3 ---
 src/context_menu/custom_context_menu.js | 28 +++++-----------------
 src/sidebar/sidebar.html                |  9 +------
 src/sidebar/sidebar.js                  | 31 +++++--------------------
 4 files changed, 13 insertions(+), 58 deletions(-)

diff --git a/src/assets/lexicon_icon.js b/src/assets/lexicon_icon.js
index 7b843b8..2929fee 100644
--- a/src/assets/lexicon_icon.js
+++ b/src/assets/lexicon_icon.js
@@ -1,5 +1,3 @@
-console.log("lexicon_icon.js chargé");
-
 /**
  * Sélectionne aléatoirement une couleur dans une palette prédéfinie.
  * @returns {string} Une couleur au format hexadécimal ou HSL.
@@ -65,7 +63,6 @@ function createColorCircle(color, size = 32) {
   return circle;
 }
 
-// Exposez ces fonctions globalement pour qu'elles soient accessibles dans d'autres scripts.
 window.generateRandomColor = generateRandomColor;
 window.getOrCreateLexiconColor = getOrCreateLexiconColor;
 window.createColorCircle = createColorCircle;
diff --git a/src/context_menu/custom_context_menu.js b/src/context_menu/custom_context_menu.js
index c37004a..ae90611 100644
--- a/src/context_menu/custom_context_menu.js
+++ b/src/context_menu/custom_context_menu.js
@@ -33,7 +33,6 @@ function injectWhiteBox() {
   if (!whiteBox) {
     whiteBox = document.createElement("div");
     whiteBox.id = WHITE_BOX_ID;
-    // Styles essentiels
     whiteBox.style.position = "absolute";
     whiteBox.style.zIndex = "9999";
     whiteBox.style.backgroundColor = "#fff";
@@ -41,7 +40,6 @@ function injectWhiteBox() {
     whiteBox.style.padding = "5px";
     whiteBox.style.borderRadius = "4px";
     whiteBox.style.boxShadow = "0px 2px 10px rgba(0,0,0,0.2)";
-    // Génération des URLs des icônes
     const addLexiconPath = browser.runtime.getURL("src/assets/icons/ajout_lexique.png");
     const getDefinitionPath = browser.runtime.getURL("src/assets/icons/definition.png");
     const loginPath = browser.runtime.getURL("src/assets/icons/connexion.png");
@@ -67,7 +65,6 @@ function injectWhiteBox() {
     document.body.appendChild(whiteBox);
     setupWhiteBoxActions();
   }
-  // Empêcher la propagation des clics dans le menu
   whiteBox.addEventListener("mouseup", (e) => {
     e.stopPropagation();
   });
@@ -186,7 +183,6 @@ function hideWhiteBox() {
 
 // Écoute globale pour la sélection de texte
 document.addEventListener("mouseup", (event) => {
-  // Si le clic se fait à l'intérieur du whiteBox, ne rien faire
   if (event.target.closest("#whiteBox")) return;
   const selectedText = window.getSelection().toString().trim();
   if (selectedText) {
@@ -222,13 +218,12 @@ browser.storage.onChanged.addListener((changes) => {
   }
 });
 
-
 // ─────────────────────────────────────────────────────────────────────────────
-// Fonctions d'API pour l'ajout d'un mot via le picker
+// Fonctions d'API pour l'ajout d'un mot via le sélecteur
 // ─────────────────────────────────────────────────────────────────────────────
 
 /**
- * Crée (ou récupère) le picker de sélection des lexiques.
+ * Crée (ou récupère) le sélecteur des lexiques.
  */
 function createPicker() {
   let picker = document.getElementById("lexiconPicker");
@@ -261,9 +256,8 @@ function createPicker() {
   return picker;
 }
 
-
 /**
- * Affiche le picker pour choisir le lexique dans lequel ajouter le mot.
+ * Affiche le sélecteur pour choisir le lexique dans lequel ajouter le mot.
  */
 async function showPicker(event, selectedText) {
   let picker = document.getElementById("lexiconPicker");
@@ -283,18 +277,14 @@ async function showPicker(event, selectedText) {
     if (!Array.isArray(lexicons) || lexicons.length === 0) {
       picker.innerHTML = "<p style='color:#333;'>Aucun lexique trouvé.</p>";
     } else {
-      // Ajout des icônes directement dans le picker
       for (const lex of lexicons) {
         const id = lex.id;
         const name = lex.category === "User"
           ? `Lexique personnel : ${lex.user?.pseudo || "Inconnu"} (${lex.id})`
           : `Lexique de groupe : ${lex.group?.name || "Inconnu"} (${lex.id})`;
 
-        // Obtenir la couleur et créer un cercle (l'icône)
         const color = await getOrCreateLexiconColor(id);
         const circleIcon = createColorCircle(color, 28); 
-
-        // Création du conteneur pour l'icône
         const iconContainer = document.createElement("div");
         iconContainer.className = "lexicon-option";
         iconContainer.dataset.lexiconId = id;
@@ -312,7 +302,6 @@ async function showPicker(event, selectedText) {
         picker.appendChild(iconContainer);
       }
 
-      // Création du bouton de validation qui passera sur une nouvelle ligne
       const confirmButton = document.createElement("button");
       confirmButton.className = "confirmButton";
       confirmButton.textContent = "Ajouter le mot";
@@ -329,7 +318,7 @@ async function showPicker(event, selectedText) {
         try {
           definitions = await fetchLexiconDefinitions(selectedText);
         } catch (error) {
-          console.error("❌ Erreur lors de la récupération des définitions :", error);
+          console.error("Erreur lors de la récupération des définitions :", error);
         }
 
         const existingLexiconIds = new Set();
@@ -354,7 +343,7 @@ async function showPicker(event, selectedText) {
         try {
           console.log(`📡 Ajout du mot "${selectedText}" dans les lexiques :`, lexiconsToAdd);
           const result = await AddWord(authToken, selectedText, lexiconsToAdd, false);
-          console.log("✅ Réponse API :", result);
+          console.log("Réponse API :", result);
 
           await new Promise(resolve => setTimeout(resolve, 300));
           browser.runtime.sendMessage({ action: "refreshUI" });
@@ -379,7 +368,6 @@ async function showPicker(event, selectedText) {
       picker.appendChild(confirmButton);
     }
 
-    // Positionner et afficher le picker
     picker.style.left = event.pageX + "px";
     picker.style.top = event.pageY + "px";
     picker.style.display = "flex";
@@ -401,17 +389,13 @@ document.addEventListener("mouseup", (event) => {
   const whiteBox = document.getElementById(WHITE_BOX_ID);
   const picker = document.getElementById("lexiconPicker");
 
-  // Masquer whiteBox si le clic est en dehors
   if (whiteBox && !whiteBox.contains(event.target)) {
     hideWhiteBox();
   }
-  
-  // Masquer picker si le clic est en dehors
   if (picker && !picker.contains(event.target)) {
     hideLexiconPicker();
   }
-
-  // Vérifier s'il y a du texte sélectionné
+  
   const selectedText = window.getSelection().toString().trim();
   if (selectedText) {
     console.log("Texte sélectionné :", selectedText);
diff --git a/src/sidebar/sidebar.html b/src/sidebar/sidebar.html
index 6d189ef..84ab2a2 100644
--- a/src/sidebar/sidebar.html
+++ b/src/sidebar/sidebar.html
@@ -164,7 +164,7 @@
       overflow: visible;
     }
 
-    /* Style uniformisé pour tous les tooltips */
+    /* Style pour tous les tooltips */
     .tooltip {
       all: unset;
       display: block;
@@ -194,7 +194,6 @@
       opacity: 1;
       transform: translateX(-50%) translateY(-5px);
     }
-    /* Positionnement ajusté si le conteneur est trop proche des bords */
     .tooltip-container.left .tooltip {
       left: 0;
       transform: translateX(0) translateY(-5px);
@@ -256,11 +255,8 @@
       filter: brightness(0) saturate(100%) invert(83%) sepia(89%) saturate(588%) hue-rotate(360deg);
     }
 
-    /* Cibler les tooltips à l'intérieur d'un bouton de surlignage */
     button.lexique-highlight-toggle .tooltip {
-      /* Réinitialiser toute influence du style global du bouton */
       all: unset;
-      /* Appliquer les styles désirés pour le tooltip */
       display: block;
       box-sizing: border-box;
       position: absolute;
@@ -284,14 +280,11 @@
       line-height: normal;
     }
 
-    /* Lors du survol du conteneur, afficher le tooltip */
     button.lexique-highlight-toggle:hover .tooltip {
       opacity: 1;
       transform: translateX(-50%) translateY(-5px);
     }
 
-
-    /* Autres styles divers */
     .lexicon-section {
       margin-bottom: 10px;
     }
diff --git a/src/sidebar/sidebar.js b/src/sidebar/sidebar.js
index c937cc6..8b80001 100644
--- a/src/sidebar/sidebar.js
+++ b/src/sidebar/sidebar.js
@@ -224,7 +224,6 @@ async function displayLexiconsWithCheckbox(lexicons) {
     const lexiqueDiv = document.createElement("div");
     lexiqueDiv.className = "lexique-item";
     
-    // Obtenir la couleur associée de façon asynchrone
     const color = await getOrCreateLexiconColor(lexiconId);
     const circleIcon = createColorCircle(color, 24);
     
@@ -255,7 +254,7 @@ async function displayLexiconsWithCheckbox(lexicons) {
     highlightButton.dataset.lexiconId = lexiconId;
     highlightButton.dataset.active = active ? "true" : "false";
     const feutreIcon = document.createElement("img");
-    feutreIcon.src = "../assets/icons/feutre.png"; // Vérifiez le chemin relatif
+    feutreIcon.src = "../assets/icons/feutre.png";
     feutreIcon.alt = "Feutre";
     feutreIcon.className = "feutre-icon";
     const highlightTooltip = document.createElement("span");
@@ -280,8 +279,6 @@ async function displayLexiconsWithCheckbox(lexicons) {
     
     highlightButton.appendChild(feutreIcon);
     highlightButton.appendChild(highlightTooltip);
-    
-    // Assemblage final
     lexiqueDiv.appendChild(iconDiv);
     lexiqueDiv.appendChild(labelSpan);
     lexiqueDiv.appendChild(checkboxContainer);
@@ -290,7 +287,6 @@ async function displayLexiconsWithCheckbox(lexicons) {
     lexiquesContainer.appendChild(lexiqueDiv);
   }
   
-  // Ajustement dynamique des tooltips (après un court délai)
   setTimeout(() => {
     const menu = document.getElementById("menu");
     if (!menu) return;
@@ -315,9 +311,6 @@ async function displayLexiconsWithCheckbox(lexicons) {
   }, 100);
 }
 
-
-
-
 function initModal() {
   console.log("initModal appelé");
   const modalOverlay = document.getElementById("modalOverlay");
@@ -353,11 +346,6 @@ async function handleAuthButtonClick() {
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Ajout d'un mot au(x) lexique(s)
 // ─────────────────────────────────────────────────────────────────────────────
-/**
- * Au clic sur le bouton "add-word-button",
- * on récupère le mot sélectionné (#motSelectionne)
- * et les lexiques cochés, puis on appelle AddWord.
- */
 async function handleAddWordClick() {
   openBlock("menuContent");
   // 1) Vérifier la présence du token et du mot
@@ -419,7 +407,7 @@ async function handleAddWordClick() {
   // 5) Déterminer les lexiques où ajouter le mot
   const lexiconsToAdd = selectedLexiconIds.filter(id => !existingLexiconIds.has(id));
   if (lexiconsToAdd.length === 0) {
-    return; // Rien à ajouter, tous les lexiques sélectionnés contiennent déjà le mot
+    return; 
   }
 
   // 6) Envoi d’une seule requête pour tous les lexiques restants
@@ -427,7 +415,7 @@ async function handleAddWordClick() {
     console.log(`📡 Envoi de l'ajout du mot "${selectedWord}" dans les lexiques :`, lexiconsToAdd);
     const result = await window.AddWord(authToken, selectedWord, lexiconsToAdd, false);
     
-    console.log("✅ Réponse API :", result);
+    console.log("Réponse API :", result);
 
     // Rafraîchir l'UI et la liste des entrées
     await new Promise(resolve => setTimeout(resolve, 300));
@@ -441,17 +429,13 @@ async function handleAddWordClick() {
     }
 
   } catch (error) {
-    console.error("❌ Erreur lors de l’ajout du mot :", error);
+    console.error("Erreur lors de l’ajout du mot :", error);
     if (lexiconResultElement) {
       lexiconResultElement.textContent = "Erreur lors de l’ajout : " + error.message;
     }
   }
 }
 
-
-
-
-
 // ─────────────────────────────────────────────────────────────────────────────
 // ▌ Réception des messages
 // ─────────────────────────────────────────────────────────────────────────────
@@ -611,18 +595,15 @@ document.addEventListener("DOMContentLoaded", async () => {
     });
   
     document.querySelectorAll('.toggle-btn').forEach(btn => {
-      // Forcer l'affichage initial à "+"
       btn.textContent = '+';
       btn.style.fontSize = '15px';
   
-      // Gestion du clic sur le bouton
       btn.addEventListener('click', (event) => {
         event.stopPropagation();
         const header = btn.parentElement;
         const content = header.nextElementSibling;
         if (content) {
           content.classList.toggle('hidden');
-          // Mettre à jour le texte du bouton selon l'état du bloc
           btn.textContent = content.classList.contains('hidden') ? '+' : '–';
         }
       });
@@ -635,10 +616,10 @@ document.querySelectorAll('.toggle-btn').forEach(btn => {
     const blockContent = this.parentElement.nextElementSibling;
     if (blockContent.classList.contains('hidden')) {
       blockContent.classList.remove('hidden');
-      this.textContent = '–'; // affiche le symbole pour fermer
+      this.textContent = '–'; 
     } else {
       blockContent.classList.add('hidden');
-      this.textContent = '+'; // affiche le symbole pour ouvrir
+      this.textContent = '+';
     }
   });
 });
-- 
GitLab