From 722311057e261050845b5c0d51bc6d7dea2ff20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pr=C3=A9nom=20Nom?= <adresse@mail.com> Date: Sat, 22 Feb 2025 06:20:37 +0100 Subject: [PATCH] affichage pos + transcription phon. dans sidebar --- src/utils/definitions.js | 324 +++++++++++++++++++++++++-------------- 1 file changed, 212 insertions(+), 112 deletions(-) diff --git a/src/utils/definitions.js b/src/utils/definitions.js index ca0a070..a510319 100644 --- a/src/utils/definitions.js +++ b/src/utils/definitions.js @@ -77,7 +77,7 @@ async function fetchLexiconDefinitions(word) { const results = await Promise.all(definitionsPromises); - // 3) Parcourir les résultats et extraire les définitions + // 3) Parcourir les résultats et extraire les définitions + prononciations let allDefinitions = []; results.forEach(result => { log(`Pour le lexique ${result.lexiconId}, entrées filtrées :`, result.entries); @@ -98,6 +98,13 @@ async function fetchLexiconDefinitions(word) { items.forEach(item => { const definitionsArray = item.Sense?.Definitions; + const pronunciationsArray = item.Sense?.Pronunciations; + + let pronunciations = []; + if (Array.isArray(pronunciationsArray)) { + pronunciations = pronunciationsArray.map(p => p.Transcription).filter(p => p); + } + if (!Array.isArray(definitionsArray)) return; definitionsArray.forEach(defObj => { @@ -105,6 +112,7 @@ async function fetchLexiconDefinitions(word) { allDefinitions.push({ source: sourceName, text: defObj.Def, + pronunciations: pronunciations, lexiconId: lexiconId }); } @@ -112,14 +120,13 @@ async function fetchLexiconDefinitions(word) { }); }); }); - log("Résultat final filtré :", allDefinitions); - return allDefinitions; - } catch (error) { - log("⌠Erreur générale lors de la récupération des définitions :", error); - return []; - } -} + return allDefinitions; + } catch (error) { + log("⌠Erreur générale lors de la récupération des définitions :", error); + return []; + } + } /** * Récupère la définition d'un mot depuis le Wiktionnaire (fr). @@ -130,11 +137,19 @@ async function fetchWiktionaryDefinition(word) { const result = await browser.storage.local.get("accessToken"); authToken = result.accessToken; + // 🔹 Initialisation d'une structure vide pour éviter les erreurs + let formattedData = { + definitions: [], + pronunciations: [], + definitionsByPOS: {} // Pour stocker les définitions triées par POS + }; + if (!authToken) { log(`🔠Requête Wiktionnaire pour "${word}"...`); if (!word || word.trim() === "") { throw new Error("âš ï¸ Mot vide, impossible d'envoyer la requête."); } + const wiktionaryURL = `https://fr.wiktionary.org/w/api.php?action=query&format=json&origin=*&prop=extracts&explaintext=true&redirects=1&titles=${encodeURIComponent(word)}`; const response = await fetch(wiktionaryURL); if (!response.ok) { @@ -145,17 +160,19 @@ async function fetchWiktionaryDefinition(word) { const pages = data.query?.pages; const page = pages ? Object.values(pages)[0] : null; - - const definitionText = page && page.extract - ? page.extract.trim() - : "âš ï¸ Aucune définition trouvée sur le Wiktionnaire."; - log("🌠Définition Wiktionnaire extraite :", definitionText); + formattedData.definitions = page && page.extract + ? [page.extract.trim()] + : ["âš ï¸ Aucune définition trouvée sur le Wiktionnaire."]; + + log("🌠Définition Wiktionnaire extraite :", formattedData.definitions); return [ { source: "Wiktionnaire", - text: definitionText + text: formattedData.definitions.join(" | "), + pronunciations: formattedData.pronunciations, + definitionsByPOS: formattedData.definitionsByPOS } ]; } else { @@ -166,27 +183,47 @@ async function fetchWiktionaryDefinition(word) { log("Réponse brute de l'API :", apiResponse); if (!Array.isArray(apiResponse) || apiResponse.length === 0) { - console.warn(`Aucune définition trouvée pour "${word}"`); - return []; // Retourne un tableau vide si aucune définition + console.warn(`Aucune définition trouvée pour "${word}"`); + return []; // Retourne un tableau vide si aucune définition } - // Formatage des données - const formattedData = formatDefinitionData(apiResponse); - log("Données formatées :", formattedData); + // 🛠Formatage des données récupérées + formattedData = formatDefinitionData(apiResponse); + log(" Données formatées :", formattedData); + + // Vérification avant retour + if (!formattedData.definitions) { + formattedData.definitions = []; // 🔹 Toujours s'assurer que cette clé existe + } + if (!formattedData.pronunciations) { + formattedData.pronunciations = []; // 🔹 Toujours s'assurer que cette clé existe + } + if (!formattedData.definitionsByPOS) { + formattedData.definitionsByPOS = {}; // 🔹 Toujours s'assurer que cette clé existe + } return [ - { - source: "Wiktionnaire", - text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "âš ï¸ Aucune définition disponible." - } + { + source: "Wiktionnaire", + text: formattedData.definitions.length > 0 ? formattedData.definitions.join(" | ") : "Aucune définition disponible.", + pronunciations: formattedData.pronunciations, + definitionsByPOS: formattedData.definitionsByPOS + } ]; } } catch (error) { log("⌠Erreur lors de la récupération de la définition :", error); - return [{ source: "Wiktionnaire", text: "Erreur lors de la récupération sur le Wiktionnaire." }]; + return [{ + source: "Wiktionnaire", + text: "Erreur lors de la récupération sur le Wiktionnaire.", + pronunciations: [], + definitionsByPOS: {} + }]; } } + + async function wikiApiResponse(word) { const result = await browser.storage.local.get("accessToken"); authToken = result.accessToken; @@ -219,47 +256,71 @@ async function wikiApiResponse(word) { function formatDefinitionData(apiResponse) { let formattedData = { word: apiResponse[0]?.id.split("-").slice(2).join("-") || "", - pronunciations: [], - definitions: [], - examples: [], - translations: {}, + pronunciations: new Set(), // Utilisation d'un Set pour éviter les doublons + definitionsByPOS: {} // Organisation par catégorie grammaticale }; apiResponse.forEach(entry => { - const wordData = entry[entry.id.split(".").slice(-1)[0]]; // Accéder aux données via la clé dynamique + const wordData = entry[entry.id.split(".").slice(-1)[0]]; // Accès aux données via clé dynamique + const pos = wordData.pos || "Autre"; // Définit le POS ou "Autre" si absent + + if (!formattedData.definitionsByPOS[pos]) { + formattedData.definitionsByPOS[pos] = { + definitions: [], + examples: [], + pronunciations: new Set() + }; + } - // Ajout des prononciations + // Ajout des prononciations globales en extrayant les transcriptions valides if (wordData.pronunciations) { - formattedData.pronunciations.push(...wordData.pronunciations); + wordData.pronunciations.forEach(pron => { + if (pron.transcript) { + formattedData.pronunciations.add(pron.transcript); + } + }); } - // Ajout des définitions + // Ajout des prononciations spécifiques au POS + if (wordData.pronunciations) { + wordData.pronunciations.forEach(pron => { + if (pron.transcript) { + formattedData.definitionsByPOS[pos].pronunciations.add(pron.transcript); + } + }); + } + + // Ajout des définitions et des exemples if (wordData.senses) { for (let senseKey in wordData.senses) { let sense = wordData.senses[senseKey]; + if (sense.Definitions) { - formattedData.definitions.push(...sense.Definitions.map(d => d.definition)); + formattedData.definitionsByPOS[pos].definitions.push( + ...sense.Definitions.map(d => d.definition) + ); } if (sense.Examples) { - formattedData.examples.push(...sense.Examples.map(e => e.example)); + formattedData.definitionsByPOS[pos].examples.push( + ...sense.Examples.map(e => e.example) + ); } } } + }); - // Ajout des traductions - if (entry.translations) { - entry.translations.forEach(translation => { - if (!formattedData.translations[translation.lang_name]) { - formattedData.translations[translation.lang_name] = []; - } - formattedData.translations[translation.lang_name].push(translation.sense); - }); - } + // Convertir les Sets en Arrays + formattedData.pronunciations = [...formattedData.pronunciations]; + Object.keys(formattedData.definitionsByPOS).forEach(pos => { + formattedData.definitionsByPOS[pos].pronunciations = [...formattedData.definitionsByPOS[pos].pronunciations]; }); return formattedData; } + + + // ───────────────────────────────────────────────────────────────────────────── // â–Œ Affichage des définitions dans la barre latérale // ───────────────────────────────────────────────────────────────────────────── @@ -278,99 +339,138 @@ function displayDefinitions(definitions) { const noLexiconDefinitionsContainer = document.getElementById("noLexiconDefinitionsContainer"); const noWiktionaryDefinitionsContainer = document.getElementById("noWiktionaryDefinitionsContainer"); + // Nettoyage des listes existantes mesLexiquesList.innerHTML = ""; wiktionnaireList.innerHTML = ""; + // Masquer les sections vides par défaut if (noLexiconDefinitionsContainer) noLexiconDefinitionsContainer.style.display = "none"; if (noWiktionaryDefinitionsContainer) noWiktionaryDefinitionsContainer.style.display = "none"; + let hasLexiconDefinitions = false; let hasWiktionaryDefinitions = false; - const lexiconGroups = {}; - definitions.forEach(({ source, text }) => { - if (!source || !text) return; - - const li = document.createElement("li"); - let displayedText = text; - - if (text.length > MAX_LENGTH) { - displayedText = text.slice(0, MAX_LENGTH) + "... "; - const readMoreLink = document.createElement("a"); - readMoreLink.href = "#"; - readMoreLink.textContent = "[Lire la suite]"; - readMoreLink.style.marginLeft = "5px"; - readMoreLink.style.color = "#8d5c70"; - readMoreLink.style.textDecoration = "underline"; - readMoreLink.style.cursor = "pointer"; - readMoreLink.addEventListener("click", (event) => { - event.preventDefault(); - openDefinitionPopup(text); + definitions.forEach(({ source, text, definitionsByPOS }) => { + if (!source || !definitionsByPOS) return; + + const definitionContainer = document.createElement("div"); + definitionContainer.classList.add("definition-item"); + + // 🔊 1. Affichage des prononciations globales si disponibles + const allPronunciations = new Set(); + Object.values(definitionsByPOS).forEach(posData => { + posData.pronunciations.forEach(pron => allPronunciations.add(pron)); }); - li.appendChild(document.createTextNode(displayedText)); - li.appendChild(readMoreLink); - } else { - li.textContent = displayedText; - } - // Vérifier la source : Wiktionnaire/Lexiques - if (source === "Wiktionnaire") { - wiktionnaireList.appendChild(li); - hasWiktionaryDefinitions = true; - } else { - if (!lexiconGroups[source]) { - lexiconGroups[source] = []; + if (allPronunciations.size > 0) { + const pronDiv = document.createElement("div"); + pronDiv.style.fontWeight = "bold"; + pronDiv.style.color = "#94608a"; + pronDiv.style.marginBottom = "5px"; + pronDiv.textContent = `Prononciations possibles : ${[...allPronunciations].join(", ")}`; + definitionContainer.appendChild(pronDiv); + } + + // 2. Affichage des définitions triées par POS + Object.entries(definitionsByPOS).forEach(([pos, posData]) => { + if (posData.definitions.length === 0) return; // Évite les POS vides + + // Titre du POS + const posTitle = document.createElement("h4"); + posTitle.style.marginTop = "10px"; + posTitle.style.color = "#e3e3e3"; + posTitle.textContent = `${pos.toUpperCase()}`; + definitionContainer.appendChild(posTitle); + + // Prononciations spécifiques au POS + if (posData.pronunciations.length > 0) { + const posPronDiv = document.createElement("div"); + posPronDiv.style.fontStyle = "italic"; + posPronDiv.style.color = "#94608a"; + // posPronDiv.textContent = `${posData.pronunciations.join(", ")}`; + // definitionContainer.appendChild(posPronDiv); + } + + // Liste des définitions + const defList = document.createElement("ul"); + defList.style.margin = "0"; + defList.style.paddingLeft = "20px"; + + posData.definitions.forEach(def => { + const li = document.createElement("li"); + + // 3. Gestion du bouton "Lire la suite" + let displayedText = def.trim(); + if (displayedText.length > MAX_LENGTH) { + const truncatedText = displayedText.slice(0, MAX_LENGTH) + "... "; + const readMoreLink = document.createElement("a"); + readMoreLink.href = "#"; + readMoreLink.textContent = "[Lire la suite]"; + readMoreLink.style.marginLeft = "5px"; + readMoreLink.style.color = "#8d5c70"; + readMoreLink.style.textDecoration = "underline"; + readMoreLink.style.cursor = "pointer"; + readMoreLink.addEventListener("click", (event) => { + event.preventDefault(); + openDefinitionPopup(displayedText); + }); + + li.appendChild(document.createTextNode(truncatedText)); + li.appendChild(readMoreLink); + } else { + li.textContent = displayedText; + } + + defList.appendChild(li); + }); + + definitionContainer.appendChild(defList); + }); + + // 4. Ajout dans la bonne section (Lexique ou Wiktionnaire) + if (source === "Wiktionnaire") { + wiktionnaireList.appendChild(definitionContainer); + hasWiktionaryDefinitions = true; + } else { + if (!lexiconGroups[source]) { + lexiconGroups[source] = []; + } + lexiconGroups[source].push(definitionContainer); + hasLexiconDefinitions = true; } - lexiconGroups[source].push(li); - hasLexiconDefinitions = true; - } }); + // 5. Gestion des groupes de lexiques personnels Object.entries(lexiconGroups).forEach(([lexiconName, definitionItems]) => { - const lexiconContainer = document.createElement("div"); - lexiconContainer.className = "lexicon-section"; - - const lexiconHeader = document.createElement("div"); - lexiconHeader.className = "lexicon-header"; - lexiconHeader.textContent = lexiconName; - lexiconHeader.addEventListener("click", () => { - lexiconContent.classList.toggle("hidden"); - }); + const lexiconContainer = document.createElement("div"); + lexiconContainer.className = "lexicon-section"; + + const lexiconHeader = document.createElement("div"); + lexiconHeader.className = "lexicon-header"; + lexiconHeader.textContent = lexiconName; + lexiconHeader.addEventListener("click", () => { + lexiconContent.classList.toggle("hidden"); + }); - const lexiconContent = document.createElement("ul"); - lexiconContent.className = "lexicon-content hidden"; + const lexiconContent = document.createElement("div"); + lexiconContent.className = "lexicon-content hidden"; - definitionItems.forEach(li => lexiconContent.appendChild(li)); + definitionItems.forEach(item => lexiconContent.appendChild(item)); - lexiconContainer.appendChild(lexiconHeader); - lexiconContainer.appendChild(lexiconContent); - mesLexiquesList.appendChild(lexiconContainer); + lexiconContainer.appendChild(lexiconHeader); + lexiconContainer.appendChild(lexiconContent); + mesLexiquesList.appendChild(lexiconContainer); }); - if (!hasLexiconDefinitions && noLexiconDefinitionsContainer) { - if (!authToken) { - noLexiconDefinitionsContainer.textContent = "Veuillez vous connecter pour accéder aux définitions de vos lexiques."; - noLexiconDefinitionsContainer.style.textAlign = "center"; - noLexiconDefinitionsContainer.style.fontStyle = "italic"; - } else { - noLexiconDefinitionsContainer.textContent = "Aucune définition trouvée dans les lexiques."; - } - noLexiconDefinitionsContainer.style.display = "block"; - } + // 6. Gestion des sections vides if (!hasWiktionaryDefinitions && noWiktionaryDefinitionsContainer) { - noWiktionaryDefinitionsContainer.style.display = "block"; - } - - const mesLexiquesContainer = document.getElementById("mesLexiquesContainer"); - if (mesLexiquesContainer) { - mesLexiquesContainer.style.display = hasLexiconDefinitions ? "block" : "none"; - } - const wiktionnaireContainer = document.getElementById("wiktionnaireContainer"); - if (wiktionnaireContainer) { - wiktionnaireContainer.style.display = hasWiktionaryDefinitions ? "block" : "none"; + noWiktionaryDefinitionsContainer.style.display = "block"; } } + + // ───────────────────────────────────────────────────────────────────────────── // â–Œ Gestion du popup pour afficher la définition complète du Wiktionnaire // ───────────────────────────────────────────────────────────────────────────── -- GitLab