Skip to content
Snippets Groups Projects
custom_context_menu.js 11.42 KiB
console.log("custom_context_menu.js chargé correctement");

// === Variables globales ===
let authToken = null;
const WHITE_BOX_ID = "whiteBox"; // Pour éviter les "magic strings"

// Récupère le token depuis le stockage local et le stocke dans authToken
async function loadAuthToken() {
  try {
    const result = await browser.storage.local.get("accessToken");
    authToken = result.accessToken || null;
    console.log("🔑 Token chargé :", authToken);
  } catch (error) {
    console.error("❌ Erreur lors de la récupération du token :", error);
    authToken = null;
  }
}

// Crée le menu contextuel personnalisé s'il n'existe pas déjà
function injectWhiteBox() {
  if (!document.getElementById(WHITE_BOX_ID)) {
    const whiteBox = document.createElement("div");
    whiteBox.id = WHITE_BOX_ID;

    // Exemple pour générer toutes les URLs
    const addLexiconPath = browser.runtime.getURL("icons/ajout_lexique.png");
    const getDefinitionPath = browser.runtime.getURL("icons/definition.png");
    const getDefinitionWikiPath = browser.runtime.getURL("icons/definition_wiktionnaire.png");
    const loginPath = browser.runtime.getURL("icons/connexion.png");

    // Construction du HTML
    whiteBox.innerHTML = `
      <p id="selectedWord">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 - Ajout lexique -->
        <div class="icon-container" title="Ajoutez ce mot à votre lexique">
          <img src="${addLexiconPath}" alt="Ajouter au lexique" class="icon" id="addLexiconButton">
        </div>

        <!-- Bouton 2 - Définition interne -->
        <div class="icon-container" title="Obtenez la définition de ce mot">
          <img src="${getDefinitionPath}" alt="Obtenir la définition" class="icon" id="getDefinitionButton">
        </div>

        <!-- Bouton 3 - Wiktionnaire -->
        <div class="icon-container" title="Rechercher dans le Wiktionnaire">
          <img src="${getDefinitionWikiPath}" alt="Wiktionnaire" class="icon" id="getDefinitionWikiButton">
        </div>

        <!-- Bouton 4 - Connexion -->
        <div class="icon-container" title="Connectez-vous à BaLex">
          <img src="${loginPath}" alt="Se connecter" class="icon" id="loginButton" style="display: none;">
        </div>
      </div>
    `;

    document.body.appendChild(whiteBox);

    // Configure les actions de chaque bouton
    setupWhiteBoxActions();
  } else {
    console.log(`#${WHITE_BOX_ID} déjà présent dans le DOM.`);
  }
}

// Configure les actions/boutons du menu
function setupWhiteBoxActions() {
  const addLexiconBtn = document.getElementById("addLexiconButton");
  const getDefinitionBtn = document.getElementById("getDefinitionButton");
  const getDefinitionWikiBtn = document.getElementById("getDefinitionWikiButton");
  const loginBtn = document.getElementById("loginButton");

  // Ajout au lexique
  addLexiconBtn.onclick = async () => {
    const selectedText = getSelectedWord();
    console.log("🔍 Ajout au lexique :", selectedText);
    if (authToken) {
      await searchLexicon(selectedText);
    } else {
      alert("⚠️ Veuillez vous connecter pour utiliser cette fonction.");
    }
  };

  // Obtenir la définition
  getDefinitionBtn.onclick = async () => {
    const selectedText = getSelectedWord();
    console.log("📖 Recherche des définitions :", selectedText);
    if (authToken) {
      await getDefinition(selectedText);
    } else {
      alert("⚠️ Veuillez vous connecter pour utiliser cette fonction.");
    }
  };

  // Définition Wiktionnaire
  getDefinitionWikiBtn.onclick = () => {
    const selectedText = getSelectedWord();
    console.log("🌐 Recherche sur le Wiktionnaire :", selectedText);
    alert(`Recherche sur le Wiktionnaire pour "${selectedText}".`);
  };

  // Login
  loginBtn.onclick = () => {
    alert("Vous allez être redirigé(e) vers la page de connexion.");
    browser.runtime.sendMessage({ action: "toggleAuth" });
  };
}

// Met à jour la visibilité des boutons en fonction de l'état de connexion
function updateMenuVisibility() {
  // S'assurer que la whiteBox est injectée
  injectWhiteBox();

  const addLexiconBtn = document.getElementById("addLexiconButton");
  const getDefinitionBtn = document.getElementById("getDefinitionButton");
  const getDefinitionWikiBtn = document.getElementById("getDefinitionWikiButton");
  const loginBtn = document.getElementById("loginButton");

  if (!addLexiconBtn || !getDefinitionBtn || !getDefinitionWikiBtn || !loginBtn) {
    console.warn("⚠️ Un des boutons n'a pas été trouvé dans le DOM.");
    return;
  }

  if (authToken) {
    // Utilisateur connecté
    addLexiconBtn.style.display = "inline-block";
    getDefinitionBtn.style.display = "inline-block";
    getDefinitionWikiBtn.style.display = "inline-block";
    loginBtn.style.display = "none";
  } else {
    // Utilisateur déconnecté
    addLexiconBtn.style.display = "none";
    getDefinitionBtn.style.display = "none";
    getDefinitionWikiBtn.style.display = "inline-block";
    loginBtn.style.display = "inline-block";
  }
}
// Récupère le mot affiché dans #selectedWord.
function getSelectedWord() {
  const selectedWordElement = document.getElementById("selectedWord");
  if (!selectedWordElement) {
    return "";
  }
  return selectedWordElement.textContent.split(": ")[1] || "";
}

// Affiche le menu contextuel (whiteBox) à la position du clic en mettant à jour le mot sélectionné.
function showWhiteBox(event, selectedText) {
  const whiteBox = document.getElementById(WHITE_BOX_ID);
  if (!whiteBox) {
    console.error(`#${WHITE_BOX_ID} introuvable dans le DOM.`);
    return;
  }

  if (selectedText) {
    // Met à jour l'affichage du mot sélectionné
    const selectedWordElement = document.getElementById("selectedWord");
    selectedWordElement.textContent = `${selectedText}`;
    
    // Récupère la position de la sélection
    const selection = window.getSelection();
    const range = selection.getRangeAt(0);
    const rect = range.getBoundingClientRect(); // Obtenez la position et taille du mot sélectionné

    // Calcule la position du menu en bas à droite du mot sélectionné
    const top = rect.bottom + window.scrollY; // Bas du mot + défilement vertical
    const left = rect.right + window.scrollX; // Droite du mot + défilement horizontal

    // Positionne la whiteBox
    whiteBox.style.left = `${left}px`;
    whiteBox.style.top = `${top}px`;
    whiteBox.style.display = "block";nsole.log("Affichage du menu contextuel avec le mot :", selectedText);

    // Mettre à jour la visibilité des boutons
    updateMenuVisibility();
  }
}

// Masque la whiteBox.
function hideWhiteBox() {
  const whiteBox = document.getElementById(WHITE_BOX_ID);
  if (whiteBox) {
    whiteBox.style.display = "none";
  }
}

// === Écoute les événements de sélection de texte (mouseup) ===
document.addEventListener("mouseup", (event) => {
  const selectedText = window.getSelection().toString().trim();
  if (selectedText) {
    console.log("Événement de sélection détecté. Texte sélectionné :", selectedText);
    injectWhiteBox(); 
    showWhiteBox(event, selectedText);

    // Envoie le mot sélectionné à la barre latérale
    browser.runtime.sendMessage({
      action: "mot_selectionne",
      selectedText,
    });
  } else {
    // Masquer le menu si rien n'est sélectionné
    hideWhiteBox();
  }
});

// Réécouter les messages envoyés par le background script
browser.runtime.onMessage.addListener((message) => {
  if (message.action === "refreshUI") {
    console.log("🔄 Mise à jour du menu contextuel personnalisé (double-clic/sélection).");
    // Recharger le token puis mettre à jour l'affichage
    loadAuthToken().then(() => {
      updateMenuVisibility();
    });
  }
});

// === Charger le token au démarrage, puis mettre à jour le menu ===
loadAuthToken().then(() => {
  injectWhiteBox();
  updateMenuVisibility();
});


// Recherche un mot dans le lexique personnel
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;
    }

    const entries = await getLexiconEntriesID(authToken, frenchLexicon.id);
    const isWordPresent = entries.some(
      (entry) => entry.graphy.toLowerCase() === selectedText.toLowerCase()
    );

    if (isWordPresent) {
      alert(`✅ Le mot "${selectedText}" est présent dans votre lexique personnel.`);
    } else {
      alert(`❌ Le mot "${selectedText}" n'est pas présent dans votre lexique personnel.`);
    }
  } catch (error) {
    console.error("❌ Erreur lors de la recherche dans le lexique :", error);
    alert(`Erreur lors de la recherche : ${error.message}`);
  }
}

// Vérifie dans quels lexiques le mot est présent
async function checkLexicon(selectedText) {
  try {
    const lexicons = await getLexicons(authToken);
    const results = lexicons.map((lexicon) => ({
      name: lexicon.name,
      isPresent: lexicon.entries.some(
        (entry) => entry.graphy.toLowerCase() === selectedText.toLowerCase()
      ),
    }));

    console.log("📋 Résultats des lexiques :", results);
    let message = `Résultats pour "${selectedText}":\n\n`;
    results.forEach(({ name, isPresent }) => {
      message += `- ${name}: ${isPresent ? "✅ Présent" : "❌ Non présent"}\n`;
    });
    alert(message);
  } catch (error) {
    console.error("❌ Erreur lors de la vérification des lexiques :", error);
    alert(`Erreur lors de la vérification : ${error.message}`);
  }
}

// Obtenir les définitions d'un mot à partir de plusieurs lexiques.
async function getDefinition(selectedText) {
  try {
    const lexicons = await getLexicons(authToken);
    let definitions = [];

    for (const lexicon of lexicons) {
      const entries = await getLexiconEntriesID(authToken, lexicon.id);
      const entry = entries.find(
        (e) => e.graphy.toLowerCase() === selectedText.toLowerCase()
      );

      if (entry) {
        const definitionData = await getDefinitionAPI(authToken, entry.id);
        // Remarque: j'ai renommé en getDefinitionAPI pour éviter
        // la confusion avec la fonction "getDefinition" ci-dessus.
        definitions.push(...extractDefinitions(definitionData));
      }
    }

    console.log("📖 Définitions trouvées :", definitions);
    if (definitions.length > 0) {
      alert(`📖 Définitions pour "${selectedText}":\n\n` + definitions.join("\n"));
    } else {
      alert(`❌ Aucune définition trouvée pour "${selectedText}".`);
    }
  } catch (error) {
    console.error("❌ Erreur lors de la récupération des définitions :", error);
    alert(`Erreur lors de la récupération des définitions : ${error.message}`);
  }
}

// Extrait un tableau de définitions à partir d'une réponse JSON de l'API.
function extractDefinitions(response) {
  if (!response || !response.attributes || !response.attributes.Items) {
    console.warn("⚠️ Structure de réponse inattendue.");
    return [];
  }

  const items = response.attributes.Items;
  return items.flatMap((item) => {
    const defs = item.Sense?.Definitions?.map((def) => def.Def || "Définition non disponible");
    return defs || [];
  });
}