Index: gc_core/js/lang_core/gc_engine.js ================================================================== --- gc_core/js/lang_core/gc_engine.js +++ gc_core/js/lang_core/gc_engine.js @@ -42,10 +42,15 @@ let _dOptionsColors = null; let _oSpellChecker = null; let _oTokenizer = null; let _aIgnoredRules = new Set(); + +function echo (x) { + console.log(x); + return true; +} var gc_engine = { //// Informations Index: gc_lang/fr/config.ini ================================================================== --- gc_lang/fr/config.ini +++ gc_lang/fr/config.ini @@ -15,26 +15,30 @@ logo = logo.png # main dictionary lexicon_src = lexicons/French.lex dic_filenames = fr-allvars,fr-classic,fr-reform -dic_name = Français,Français (Classique/Moderne),Français (Réforme 1990) +dic_name = fr-allvars,fr-classic,fr-reform +dic_description = Français (Toutes variantes),Français (Classique),Français (Réforme 1990) dic_filter = ,[*CMPX]$,[*RPX]$ dic_default_filename_py = fr-allvars dic_default_filename_js = fr-allvars # extended dictionary lexicon_extended_src = lexicons/French.extended.lex dic_extended_filename = fr.extended -dic_extended_name = Français - dictionnaire étendu +dic_extended_name = fr.extended +dic_extended_description = Français - dictionnaire étendu # community dictionary lexicon_community_src = lexicons/French.community.lex dic_community_filename = fr.community -dic_community_name = Français - dictionnaire communautaire +dic_community_name = fr.community +dic_community_description = Français - dictionnaire communautaire # personal dictionary lexicon_personal_src = lexicons/French.personal.lex dic_personal_filename = fr.personal -dic_personal_name = Français - dictionnaire personnel +dic_personal_name = fr.personal +dic_personal_description = Français - dictionnaire personnel # Finite state automaton compression: 1, 2 (experimental) or 3 (experimental) fsa_method = 1 # stemming method: S for suffixes only, A for prefixes and suffixes stemming_method = S Index: gc_lang/fr/dictionnaire/genfrdic.py ================================================================== --- gc_lang/fr/dictionnaire/genfrdic.py +++ gc_lang/fr/dictionnaire/genfrdic.py @@ -524,15 +524,10 @@ def writeGrammarCheckerLexicon (self, spfDst, version): echo(' * Lexique simplifié >> [ {} ] '.format(spfDst)) with open(spfDst[:-4]+".lex", 'w', encoding='utf-8', newline="\n") as hDst: hDst.write(MPLHEADER) hDst.write("# Lexique simplifié pour Grammalecte v{}\n# Licence : MPL v2.0\n\n".format(version)) - hDst.write("## LangCode: fr\n") - hDst.write("## LangName: Français\n") - hDst.write("## DicName: fr.commun\n") - hDst.write("## Description: Français commun (toutes variantes)\n") - hDst.write("## Author: Olivier R.\n\n") hDst.write(Flexion.simpleHeader()) for oFlex in self.lFlexions: hDst.write(oFlex.getGrammarCheckerRepr()) def createFiles (self, spDst, lDictVars, nMode, bSimplified): Index: gc_lang/fr/modules-js/lexicographe.js ================================================================== --- gc_lang/fr/modules-js/lexicographe.js +++ gc_lang/fr/modules-js/lexicographe.js @@ -459,36 +459,40 @@ } } } getListOfTokensReduc (sText, bInfo=true) { - let aTokenList = this.getListOfTokens(sText.replace("'", "’").trim(), false); - let iKey = 0; + let lToken = this.getListOfTokens(sText.replace("'", "’").trim(), false); + let iToken = 0; let aElem = []; + if (lToken.length == 0) { + return aElem; + } do { - let oToken = aTokenList[iKey]; + let oToken = lToken[iToken]; let sMorphLoc = ''; let aTokenTempList = [oToken]; if (oToken.sType == "WORD" || oToken.sType == "WORD_ELIDED"){ - let iKeyTree = iKey + 1; + let iLocEnd = iToken + 1; let oLocNode = this.oLocGraph[oToken.sValue.toLowerCase()]; while (oLocNode) { - let oTokenNext = aTokenList[iKeyTree]; - iKeyTree++; + let oTokenNext = lToken[iLocEnd]; + iLocEnd++; if (oTokenNext) { oLocNode = oLocNode[oTokenNext.sValue.toLowerCase()]; } - if (oLocNode && iKeyTree <= aTokenList.length) { + if (oLocNode && iLocEnd <= lToken.length) { sMorphLoc = oLocNode["_:_"]; aTokenTempList.push(oTokenNext); } else { break; } } } if (sMorphLoc) { + // we have a locution let sValue = ''; for (let oTokenWord of aTokenTempList) { sValue += oTokenWord.sValue+' '; } let oTokenLocution = { @@ -522,26 +526,27 @@ aSubElem: aSubElem }); } else { aElem.push(oTokenLocution); } - iKey = iKey + aTokenTempList.length; + iToken = iToken + aTokenTempList.length; } else { + // No locution, we just add information if (bInfo) { let aRes = this.getInfoForToken(oToken); if (aRes) { aElem.push(aRes); } } else { aElem.push(oToken); } - iKey++; + iToken++; } - } while (iKey < aTokenList.length); + } while (iToken < lToken.length); return aElem; } } if (typeof(exports) !== 'undefined') { exports.Lexicographe = Lexicographe; } Index: gc_lang/fr/oxt/DictOptions/LexiconEditor.py ================================================================== --- gc_lang/fr/oxt/DictOptions/LexiconEditor.py +++ gc_lang/fr/oxt/DictOptions/LexiconEditor.py @@ -409,11 +409,11 @@ xGridDataModel = self.xGridModelLex.GridDataModel lEntry = [] for i in range(xGridDataModel.RowCount): lEntry.append(xGridDataModel.getRowData(i)) if lEntry: - oDAWG = dawg.DAWG(lEntry, "S", "fr", "Français", "fr.personal") + oDAWG = dawg.DAWG(lEntry, "S", "fr", "Français", "fr.personal", "Dictionnaire personnel") self.oPersonalDicJSON = oDAWG.getBinaryAsJSON() self.xOptionNode.setPropertyValue("personal_dic", json.dumps(self.oPersonalDicJSON, ensure_ascii=False)) self.xSettingNode.commitChanges() self.xNumDic.Label = str(self.oPersonalDicJSON["nEntry"]) self.xDateDic.Label = self.oPersonalDicJSON["sDate"] Index: gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-classique.aff ================================================================== --- gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-classique.aff +++ gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-classique.aff @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # AFFIXES DU DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “CLASSIQUE” v7.0 # par Olivier R. -- licence MPL 2.0 -# Généré le 09-01-2019 à 18:08 +# Généré le 11-01-2019 à 17:14 # Pour améliorer le dictionnaire, allez sur https://grammalecte.net/ SET UTF-8 Index: gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-moderne.aff ================================================================== --- gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-moderne.aff +++ gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-moderne.aff @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # AFFIXES DU DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “MODERNE” v7.0 # par Olivier R. -- licence MPL 2.0 -# Généré le 09-01-2019 à 18:08 +# Généré le 11-01-2019 à 17:14 # Pour améliorer le dictionnaire, allez sur https://grammalecte.net/ SET UTF-8 Index: gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-reforme1990.aff ================================================================== --- gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-reforme1990.aff +++ gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-reforme1990.aff @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # AFFIXES DU DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “RÉFORME 1990” v7.0 # par Olivier R. -- licence MPL 2.0 -# Généré le 09-01-2019 à 18:08 +# Généré le 11-01-2019 à 17:14 # Pour améliorer le dictionnaire, allez sur https://grammalecte.net/ SET UTF-8 Index: gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-toutesvariantes.aff ================================================================== --- gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-toutesvariantes.aff +++ gc_lang/fr/oxt/Dictionnaires/dictionaries/fr-toutesvariantes.aff @@ -2,11 +2,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # AFFIXES DU DICTIONNAIRE ORTHOGRAPHIQUE FRANÇAIS “TOUTES VARIANTES” v7.0 # par Olivier R. -- licence MPL 2.0 -# Généré le 09-01-2019 à 18:08 +# Généré le 11-01-2019 à 17:14 # Pour améliorer le dictionnaire, allez sur https://grammalecte.net/ SET UTF-8 Index: gc_lang/fr/rules.grx ================================================================== --- gc_lang/fr/rules.grx +++ gc_lang/fr/rules.grx @@ -505,11 +505,11 @@ __[s>(p_Mr_Mgr_Mme_point)__ M(?:r|gr|me) [A-ZÉ]([.])(?=\W+[a-zéèêâîïû]) @@$ <<- ~1>> * # Patronyme réduit à une seule lettre __[s](p_prénom_lettre_point_patronyme)__ - ([A-ZÉÈÂÎ][\w-]+)[ ][A-ZÉÈÂ]([.])[ ]([A-ZÉÈÂ][\w-]+) @@0,$,$ + ([A-ZÉÈÂÎ][\w-]+)[ ][A-ZÉÈÂ]([.])[ ]([A-ZÉÈÂ][\w-]+) @@0,*,$ <<- morph(\1, ":M[12]") and (morph(\3, ":(?:M[12]|V)") or not spell(\3)) ~2>> * __[s>(p_prénom_lettre_point)__ ([A-ZÉÈÂÎ][\w-]+)[ ][A-ZÉÈÂ]([.]) @@0,$ <<- morph(\1, ":M[12]") and after("^\\W+[a-zéèêîïâ]") ~2>> _ @@ -741,11 +741,11 @@ !! !! __[i>/poncfin__ ({w_1}) *$ @@0 - <<- before("\\w+(?:[.]|[ ][!?]) +(?:[A-ZÉÈÎ]\\w+|[ÀÔ])") -1>> \1.|\1 !|\1 ? # Il semble manquer une ponctuation finale (s’il s’agit d’un titre, le point final n’est pas requis). + <<- before("\\w+(?:\\.|[ ][!?]) +(?:[A-ZÉÈÎ]\\w+|[ÀÔ])") -1>> \1.|\1 !|\1 ? # Il semble manquer une ponctuation finale (s’il s’agit d’un titre, le point final n’est pas requis). TEST: __poncfin__ Vraiment. Quel {{ennui}} TEST: Internet : le nouvel eldorado TEST: OMC-FMI : Les nouveaux maîtres du monde @@ -20030,11 +20030,10 @@ TEST: Celles de l’Institut sont plus perfectionnées TEST: Judith A. Allan a aussi constaté que les études sur les crises de la masculinité ne proposent pas ou que très rarement d’indicateurs pour déterminer si une société est (trop) féminisée et si les hommes sont (réellement) en crise. TEST: une procédure abusive pour fermer la porte qu’elles ont essayé d’ouvrir TEST: En France, les hauts fonctionnaires gagnent en moyenne 7850 euros net TEST: Il faut avoir du pouvoir et des ressources - !!! Tests historiques !! ## Version 0.5.14 Index: gc_lang/fr/tb/content/lex_editor.js ================================================================== --- gc_lang/fr/tb/content/lex_editor.js +++ gc_lang/fr/tb/content/lex_editor.js @@ -476,11 +476,11 @@ build: function () { let xProgressNode = document.getElementById("wait_progress"); let lEntry = oLexiconTable.getEntries(); if (lEntry.length > 0) { - let oDAWG = new DAWG(lEntry, "S", "fr", "Français", "fr.personal", xProgressNode); + let oDAWG = new DAWG(lEntry, "S", "fr", "Français", "fr.personal", "Dictionnaire personnel", xProgressNode); let oJSON = oDAWG.createBinaryJSON(1); oFileHandler.saveFile("fr.personal.json", JSON.stringify(oJSON)); this.oIBDAWG = new IBDAWG(oJSON); this.setDictData(this.oIBDAWG.nEntry, this.oIBDAWG.sDate); //browser.runtime.sendMessage({ sCommand: "setDictionary", dParam: {sType: "personal", oDict: oJSON}, dInfo: {} }); Index: gc_lang/fr/webext/background.js ================================================================== --- gc_lang/fr/webext/background.js +++ gc_lang/fr/webext/background.js @@ -117,25 +117,22 @@ dParam: { sDictionary: sDictionary, bActivate: bActivate }, dInfo: {} }); } -function initSCOptions (dSavedOptions) { - if (!dSavedOptions.hasOwnProperty("sc_options")) { +function initSCOptions (oData) { + if (!oData.hasOwnProperty("sc_options")) { browser.storage.local.set({"sc_options": { extended: true, community: true, personal: true }}); - setDictionaryOnOff("extended", true); setDictionaryOnOff("community", true); setDictionaryOnOff("personal", true); } else { - let dOptions = dSavedOptions.sc_options; - setDictionaryOnOff("extended", dOptions["extended"]); - setDictionaryOnOff("community", dOptions["community"]); - setDictionaryOnOff("personal", dOptions["personal"]); + setDictionaryOnOff("community", oData.sc_options["community"]); + setDictionaryOnOff("personal", oData.sc_options["personal"]); } } function setDictionary (sDictionary, oDictionary) { xGCEWorker.postMessage({ @@ -143,37 +140,41 @@ dParam: { sDictionary: sDictionary, oDict: oDictionary }, dInfo: {} }); } -function setSpellingDictionary (dSavedDictionary) { - if (dSavedDictionary.hasOwnProperty("oExtendedDictionary")) { - setDictionary("extended", dSavedDictionary["oExtendedDictionary"]); - } - if (dSavedDictionary.hasOwnProperty("oCommunityDictionary")) { - setDictionary("community", dSavedDictionary["oCommunityDictionary"]); - } - if (dSavedDictionary.hasOwnProperty("oPersonalDictionary")) { - setDictionary("personal", dSavedDictionary["oPersonalDictionary"]); +function setSpellingDictionaries (oData) { + if (oData.hasOwnProperty("oPersonalDictionary")) { + // deprecated (to be removed in 2020) + console.log("personal dictionary migration"); + browser.storage.local.set({ "personal_dictionary": oData["oPersonalDictionary"] }); + setDictionary("personal", oData["oPersonalDictionary"]); + browser.storage.local.remove("oPersonalDictionary"); + } + if (oData.hasOwnProperty("personal_dictionary")) { + setDictionary("personal", oData["personal_dictionary"]); + } + if (oData.hasOwnProperty("community_dictionary")) { + setDictionary("community", oData["community_dictionary"]); } } function init () { if (bChrome) { browser.storage.local.get("gc_options", initGrammarChecker); browser.storage.local.get("ui_options", initUIOptions); - browser.storage.local.get("oExtendedDictionary", setSpellingDictionary); - browser.storage.local.get("oCommunityDictionary", setSpellingDictionary); - browser.storage.local.get("oPersonalDictionary", setSpellingDictionary); + browser.storage.local.get("personal_dictionary", setSpellingDictionaries); + browser.storage.local.get("community_dictionary", setSpellingDictionaries); + browser.storage.local.get("oPersonalDictionary", setSpellingDictionaries); // deprecated browser.storage.local.get("sc_options", initSCOptions); return; } browser.storage.local.get("gc_options").then(initGrammarChecker, showError); browser.storage.local.get("ui_options").then(initUIOptions, showError); - browser.storage.local.get("oExtendedDictionary").then(setSpellingDictionary, showError); - browser.storage.local.get("oCommunityDictionary").then(setSpellingDictionary, showError); - browser.storage.local.get("oPersonalDictionary").then(setSpellingDictionary, showError); + browser.storage.local.get("personal_dictionary").then(setSpellingDictionaries, showError); + browser.storage.local.get("community_dictionary").then(setSpellingDictionaries, showError); + browser.storage.local.get("oPersonalDictionary").then(setSpellingDictionaries, showError); // deprecated browser.storage.local.get("sc_options").then(initSCOptions, showError); } init(); @@ -215,10 +216,19 @@ xGCEWorker.postMessage(oRequest); break; case "openURL": browser.tabs.create({url: dParam.sURL}); break; + case "openConjugueurTab": + openConjugueurTab(); + break; + case "openLexiconEditor": + openLexiconEditor(dParam["dictionary"]); + break; + case "openDictionaries": + openDictionaries(); + break; default: console.log("[background] Unknown command: " + sCommand); console.log(oRequest); } //sendResponse({response: "response from background script"}); @@ -226,10 +236,11 @@ browser.runtime.onMessage.addListener(handleMessage); function handleConnexion (xPort) { + // Messages from tabs let iPortId = xPort.sender.tab.id; // identifier for the port: each port can be found at dConnx[iPortId] dConnx.set(iPortId, xPort); xPort.onMessage.addListener(function (oRequest) { let {sCommand, dParam, dInfo} = oRequest; switch (sCommand) { @@ -277,13 +288,15 @@ browser.contextMenus.create({ id: "separator_editable", type: "separator", contexts: ["editable"] }); // Page browser.contextMenus.create({ id: "rightClickLxgPage", title: "Lexicographe (page)", contexts: ["all"] }); // on all parts, due to unwanted selection browser.contextMenus.create({ id: "rightClickGCPage", title: "Correction grammaticale (page)", contexts: ["all"] }); browser.contextMenus.create({ id: "separator_page", type: "separator", contexts: ["all"] }); -// Conjugueur +// Tools browser.contextMenus.create({ id: "conjugueur_window", title: "Conjugueur [fenêtre]", contexts: ["all"] }); browser.contextMenus.create({ id: "conjugueur_tab", title: "Conjugueur [onglet]", contexts: ["all"] }); +browser.contextMenus.create({ id: "dictionaries", title: "Dictionnaires", contexts: ["all"] }); +browser.contextMenus.create({ id: "lexicon_editor", title: "Éditeur lexical", contexts: ["all"] }); // Rescan page browser.contextMenus.create({ id: "separator_rescan", type: "separator", contexts: ["editable"] }); browser.contextMenus.create({ id: "rescanPage", title: "Rechercher à nouveau les zones de texte", contexts: ["editable"] }); @@ -323,10 +336,16 @@ openConjugueurWindow(); break; case "conjugueur_tab": openConjugueurTab(); break; + case "lexicon_editor": + openLexiconEditor(); + break; + case "dictionaries": + openDictionaries(); + break; // rescan page case "rescanPage": let xPort = dConnx.get(xTab.id); xPort.postMessage({sActionDone: "rescanPage"}); break; @@ -341,22 +360,50 @@ /* Keyboard shortcuts */ browser.commands.onCommand.addListener(function (sCommand) { switch (sCommand) { + case "lexicographer": + sendCommandToCurrentTab("shortcutLexicographer"); + break; + case "text_formatter": + sendCommandToCurrentTab("shortcutTextFormatter"); + break; + case "grammar_checker": + sendCommandToCurrentTab("shortcutGrammarChecker"); + break; case "conjugueur_tab": openConjugueurTab(); break; case "conjugueur_window": openConjugueurWindow(); break; - case "lex_editor": - openLexEditor(); + case "lexicon_editor": + openLexiconEditor(); + break; + case "dictionaries": + openDictionaries(); break; } }); + +/* + Tabs +*/ +let nTabLexiconEditor = null; +let nTabDictionaries = null; +let nTabConjugueur = null; + +browser.tabs.onRemoved.addListener(function (nTabId, xRemoveInfo) { + switch (nTabId) { + case nTabLexiconEditor: nTabLexiconEditor = null; break; + case nTabDictionaries: nTabDictionaries = null; break; + case nTabConjugueur: nTabConjugueur = null; break; + } +}); + /* Actions */ @@ -370,34 +417,93 @@ function sendCommandToTab (sCommand, iTab) { let xTabPort = dConnx.get(iTab); xTabPort.postMessage({sActionDone: sCommand, result: null, dInfo: null, bEnd: false, bError: false}); } -function openLexEditor () { - if (bChrome) { - browser.tabs.create({ - url: browser.extension.getURL("panel/lex_editor.html") - }); - return; - } - let xLexEditor = browser.tabs.create({ - url: browser.extension.getURL("panel/lex_editor.html") - }); - xLexEditor.then(onCreated, onError); -} - -function openConjugueurTab () { - if (bChrome) { - browser.tabs.create({ - url: browser.extension.getURL("panel/conjugueur.html") - }); - return; - } - let xConjTab = browser.tabs.create({ - url: browser.extension.getURL("panel/conjugueur.html") - }); - xConjTab.then(onCreated, onError); +function sendCommandToCurrentTab (sCommand) { + console.log(sCommand); + if (bChrome) { + browser.tabs.query({ currentWindow: true, active: true }, (lTabs) => { + for (let xTab of lTabs) { + console.log(xTab); + browser.tabs.sendMessage(xTab.id, {sActionRequest: sCommand}); + } + }); + return; + } + browser.tabs.query({ currentWindow: true, active: true }).then((lTabs) => { + for (let xTab of lTabs) { + console.log(xTab); + browser.tabs.sendMessage(xTab.id, {sActionRequest: sCommand}); + } + }, onError); +} + +function openLexiconEditor (sName="__personal__") { + if (nTabLexiconEditor === null) { + if (bChrome) { + browser.tabs.create({ + url: browser.extension.getURL("panel/lex_editor.html") + }, onLexiconEditorOpened); + return; + } + let xLexEditor = browser.tabs.create({ + url: browser.extension.getURL("panel/lex_editor.html") + }); + xLexEditor.then(onLexiconEditorOpened, onError); + } + else { + browser.tabs.update(nTabLexiconEditor, {active: true}); + } +} + +function onLexiconEditorOpened (xTab) { + nTabLexiconEditor = xTab.id; +} + +function openDictionaries () { + if (nTabDictionaries === null) { + if (bChrome) { + browser.tabs.create({ + url: browser.extension.getURL("panel/dictionaries.html") + }, onDictionariesOpened); + return; + } + let xLexEditor = browser.tabs.create({ + url: browser.extension.getURL("panel/dictionaries.html") + }); + xLexEditor.then(onDictionariesOpened, onError); + } + else { + browser.tabs.update(nTabDictionaries, {active: true}); + } +} + +function onDictionariesOpened (xTab) { + nTabDictionaries = xTab.id; +} + +function openConjugueurTab () { + if (nTabDictionaries === null) { + if (bChrome) { + browser.tabs.create({ + url: browser.extension.getURL("panel/conjugueur.html") + }, onConjugueurOpened); + return; + } + let xConjTab = browser.tabs.create({ + url: browser.extension.getURL("panel/conjugueur.html") + }); + xConjTab.then(onConjugueurOpened, onError); + } + else { + browser.tabs.update(nTabConjugueur, {active: true}); + } +} + +function onConjugueurOpened (xTab) { + nTabConjugueur = xTab.id; } function openConjugueurWindow () { if (bChrome) { browser.windows.create({ @@ -412,16 +518,11 @@ url: browser.extension.getURL("panel/conjugueur.html"), type: "popup", width: 710, height: 980 }); - xConjWindow.then(onCreated, onError); } -function onCreated (xWindowInfo) { - //console.log(`Created window: ${xWindowInfo.id}`); -} - -function onError (error) { - console.log(`Error: ${error}`); +function onError (e) { + console.error(e); } Index: gc_lang/fr/webext/content_scripts/init.js ================================================================== --- gc_lang/fr/webext/content_scripts/init.js +++ gc_lang/fr/webext/content_scripts/init.js @@ -101,23 +101,22 @@ } } }, observePage: function () { - /* - When a textarea is added via jascript we add the menu :) - */ + // When a textarea is added via jascript we add the menu + let that = this; this.xObserver = new MutationObserver(function (mutations) { mutations.forEach(function (mutation) { for (let i = 0; i < mutation.addedNodes.length; i++){ if (mutation.addedNodes[i].tagName == "TEXTAREA") { - if (this.oOptions === null || this.oOptions.textarea) { + if (that.oOptions === null || that.oOptions.textarea) { oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, mutation.addedNodes[i])); oGrammalecte.nMenu += 1; } } else if (mutation.addedNodes[i].getElementsByTagName) { - if (this.oOptions === null || this.oOptions.textarea) { + if (that.oOptions === null || that.oOptions.textarea) { for (let xNode of mutation.addedNodes[i].getElementsByTagName("textarea")) { oGrammalecte.lMenu.push(new GrammalecteMenu(oGrammalecte.nMenu, xNode)); oGrammalecte.nMenu += 1; } } @@ -254,11 +253,10 @@ */ let xGrammalectePort = browser.runtime.connect({name: "content-script port"}); xGrammalectePort.onMessage.addListener(function (oMessage) { let {sActionDone, result, dInfo, bEnd, bError} = oMessage; - let sText = ""; switch (sActionDone) { case "init": oGrammalecte.sExtensionUrl = oMessage.sUrl; // Start oGrammalecte.listenRightClick(); @@ -290,63 +288,41 @@ (Context menu are initialized in background) */ // Grammar checker commands case "rightClickGCEditableNode": if (oGrammalecte.xRightClickedNode !== null) { - oGrammalecte.startGCPanel(oGrammalecte.xRightClickedNode); - sText = (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA") ? oGrammalecte.xRightClickedNode.value : oGrammalecte.xRightClickedNode.innerText; - xGrammalectePort.postMessage({ - sCommand: "parseAndSpellcheck", - dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false}, - dInfo: {sTextAreaId: oGrammalecte.xRightClickedNode.id} - }); + parseAndSpellcheckEditableNode(oGrammalecte.xRightClickedNode); } else { oGrammalecte.showMessage("Erreur. Le node sur lequel vous avez cliqué n’a pas pu être identifié. Sélectionnez le texte à corriger et relancez le correcteur via le menu contextuel."); } break; case "rightClickGCPage": - oGrammalecte.startGCPanel(); - xGrammalectePort.postMessage({ - sCommand: "parseAndSpellcheck", - dParam: {sText: oGrammalecte.getPageText(), sCountry: "FR", bDebug: false, bContext: false}, - dInfo: {} - }); + parseAndSpellcheckPage(); break; case "rightClickGCSelectedText": oGrammalecte.startGCPanel(); // selected text is sent to the GC worker in the background script. break; // Lexicographer commands case "rightClickLxgEditableNode": if (oGrammalecte.xRightClickedNode !== null) { - oGrammalecte.startLxgPanel(); - sText = (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA") ? oGrammalecte.xRightClickedNode.value : oGrammalecte.xRightClickedNode.innerText; - xGrammalectePort.postMessage({ - sCommand: "getListOfTokens", - dParam: {sText: sText}, - dInfo: {sTextAreaId: oGrammalecte.xRightClickedNode.id} - }); + lexicographerEditableNode(oGrammalecte.xRightClickedNode); } else { oGrammalecte.showMessage("Erreur. Le node sur lequel vous avez cliqué n’a pas pu être identifié. Sélectionnez le texte à analyser et relancez le lexicographe via le menu contextuel."); } break; case "rightClickLxgPage": - oGrammalecte.startLxgPanel(); - xGrammalectePort.postMessage({ - sCommand: "getListOfTokens", - dParam: {sText: oGrammalecte.getPageText()}, - dInfo: {} - }); + lexicographerPage(); break; case "rightClickLxgSelectedText": oGrammalecte.startLxgPanel(); // selected text is sent to the GC worker in the background script. break; // Text formatter command case "rightClickTFEditableNode": if (oGrammalecte.xRightClickedNode !== null) { - if (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA") { + if (oGrammalecte.xRightClickedNode.tagName == "TEXTAREA" || oGrammalecte.xRightClickedNode.tagName == "INPUT") { oGrammalecte.startFTPanel(oGrammalecte.xRightClickedNode); } else { oGrammalecte.showMessage("Cette zone de texte n’est pas réellement un champ de formulaire, mais un node HTML éditable. Le formateur de texte n’est pas disponible pour ce type de champ de saisie."); } } else { @@ -355,9 +331,86 @@ break; // rescan page command case "rescanPage": oGrammalecte.rescanPage(); break; + + } +}); + + +/* + Other messages from background +*/ +browser.runtime.onMessage.addListener(function (oMessage) { + let {sActionRequest} = oMessage; + let xActiveNode = document.activeElement; + switch (sActionRequest) { + /* + Commands received from the keyboard (shortcuts) + */ + case "shortcutLexicographer": + if (xActiveNode && (xActiveNode.tagName == "TEXTAREA" || xActiveNode.tagName == "INPUT")) { + lexicographerEditableNode(xActiveNode); + } else { + lexicographerPage(); + } + break; + case "shortcutTextFormatter": + if (xActiveNode && (xActiveNode.tagName == "TEXTAREA" || xActiveNode.tagName == "INPUT")) { + oGrammalecte.startFTPanel(xActiveNode); + } + break; + case "shortcutGrammarChecker": + if (xActiveNode && (xActiveNode.tagName == "TEXTAREA" || xActiveNode.tagName == "INPUT")) { + parseAndSpellcheckEditableNode(xActiveNode); + } else { + parseAndSpellcheckPage(); + } + break; default: console.log("[Content script] Unknown command: " + sActionDone); } }); + + +/* + Actions +*/ + +function parseAndSpellcheckPage () { + oGrammalecte.startGCPanel(); + xGrammalectePort.postMessage({ + sCommand: "parseAndSpellcheck", + dParam: {sText: oGrammalecte.getPageText(), sCountry: "FR", bDebug: false, bContext: false}, + dInfo: {} + }); +} + +function parseAndSpellcheckEditableNode (xNode) { + oGrammalecte.startGCPanel(xNode); + let sText = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT") ? xNode.value : xNode.innerText; + xGrammalectePort.postMessage({ + sCommand: "parseAndSpellcheck", + dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false}, + dInfo: {sTextAreaId: xNode.id} + }); +} + +function lexicographerPage () { + oGrammalecte.startLxgPanel(); + xGrammalectePort.postMessage({ + sCommand: "getListOfTokens", + dParam: {sText: oGrammalecte.getPageText()}, + dInfo: {} + }); +} + +function lexicographerEditableNode (xNode) { + oGrammalecte.startLxgPanel(); + let sText = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT") ? xNode.value : xNode.innerText; + xGrammalectePort.postMessage({ + sCommand: "getListOfTokens", + dParam: {sText: sText}, + dInfo: {sTextAreaId: xNode.id} + }); +} Index: gc_lang/fr/webext/content_scripts/panel_gc.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel_gc.js +++ gc_lang/fr/webext/content_scripts/panel_gc.js @@ -62,11 +62,11 @@ start (xNode=null) { this.oTooltip.hide(); this.clear(); if (xNode) { this.oNodeControl.setNode(xNode); - if (xNode.tagName != "TEXTAREA") { + if (!(xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT")) { this.addMessage("Note : cette zone de texte n’est pas un champ de formulaire “textarea” mais un node HTML éditable. Une telle zone de texte est susceptible de contenir des éléments non textuels qui seront effacés lors de la correction."); } } } @@ -463,11 +463,11 @@ } setNode (xNode) { this.clear(); this.xNode = xNode; - this.bTextArea = (xNode.tagName == "TEXTAREA"); + this.bTextArea = (xNode.tagName == "TEXTAREA" || xNode.tagName == "INPUT"); this.xNode.disabled = true; this._loadText(); } clear () { Index: gc_lang/fr/webext/gce_worker.js ================================================================== --- gc_lang/fr/webext/gce_worker.js +++ gc_lang/fr/webext/gce_worker.js @@ -318,13 +318,10 @@ //console.log("setDictionary", sDictionary); switch (sDictionary) { case "main": oSpellChecker.setMainDictionary(oDict); break; - case "extended": - oSpellChecker.setExtendedDictionary(oDict); - break; case "community": oSpellChecker.setCommunityDictionary(oDict); break; case "personal": oSpellChecker.setPersonalDictionary(oDict); @@ -340,17 +337,10 @@ postMessage(createResponse("setDictionary", "# Error. SpellChecker not loaded.", dInfo, true)); return; } //console.log("setDictionaryOnOff", sDictionary, bActivate); switch (sDictionary) { - case "extended": - if (bActivate) { - oSpellChecker.activateExtendedDictionary(); - } else { - oSpellChecker.deactivateExtendedDictionary(); - } - break; case "community": if (bActivate) { oSpellChecker.activateCommunityDictionary(); } else { oSpellChecker.deactivateCommunityDictionary(); Index: gc_lang/fr/webext/manifest.json ================================================================== --- gc_lang/fr/webext/manifest.json +++ gc_lang/fr/webext/manifest.json @@ -78,27 +78,37 @@ "run_at": "document_idle" } ], "commands": { + "lexicographer": { + "suggested_key": { "default": "Ctrl+Shift+L" }, + "description": "Ouvre le lexicographe" + }, + "text_formatter": { + "suggested_key": { "default": "Ctrl+Shift+F" }, + "description": "Ouvre le formateur de texte" + }, + "grammar_checker": { + "suggested_key": { "default": "Ctrl+Shift+V" }, + "description": "Ouvre le correcteur grammatical" + }, "conjugueur_tab": { - "suggested_key": { - "default": "Ctrl+Shift+6" - }, + "suggested_key": { "default": "Ctrl+Shift+6" }, "description": "Ouvre le conjugueur dans un onglet" }, "conjugueur_window": { - "suggested_key": { - "default": "Ctrl+Shift+7" - }, + "suggested_key": { "default": "Ctrl+Shift+7" }, "description": "Ouvre le conjugueur dans une fenêtre" }, - "lex_editor": { - "suggested_key": { - "default": "Ctrl+Shift+8" - }, + "lexicon_editor": { + "suggested_key": { "default": "Ctrl+Shift+8" }, "description": "Ouvre l’éditeur lexical" + }, + "dictionaries": { + "suggested_key": { "default": "Ctrl+Shift+9" }, + "description": "Ouvre le gestionnaire de dictionnaires communautaires" } }, "web_accessible_resources": [ "content_scripts/panel.css", @@ -116,12 +126,15 @@ "grammalecte/fr/tests_data.json", "img/logo-16.png" ], "permissions": [ + "*://localhost/*", + "*://dic.grammalecte.net/*", "activeTab", "contextMenus", + "cookies", "downloads", "storage" ], "chrome_settings_overrides": { ADDED gc_lang/fr/webext/panel/dictionaries.css Index: gc_lang/fr/webext/panel/dictionaries.css ================================================================== --- /dev/null +++ gc_lang/fr/webext/panel/dictionaries.css @@ -0,0 +1,193 @@ +/* + CSS Document + White + Design par Olivier R. +*/ + +* { margin: 0; padding: 0; } +img { border: none; } + + +/* Generic classes */ + +.fleft { float: left; } +.fright { float: right; } +.center { text-align: center; } +.right { text-align: right; } +.left { text-align: left; } +.justify { text-align: justify; } +.hidden { display: none; } +.clearer { clear: both; font-size: 0; height: 0; } + +body { + background: hsl(0, 0%, 100%) url(../img/lines.png); + font: normal 16px "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif; + color: #505050; +} + +.inbox { + width: 800px; + margin: 20px auto 10px auto; + padding: 10px 30px 30px 30px; + background: hsl(0, 0%, 100%); + border: 2px solid hsl(210, 0%, 90%); + border-radius: 20px; +} + + +#message_box { + display: none; + position: fixed; + top: 33%; + left: calc(50% - 325px); +} +#message { + display: inline-block; + padding: 5px 20px; + width: 600px; + background-color: hsl(0, 50%, 50%); + color: hsl(0, 50%, 98%); + border-style: solid; + border-width: 3px 0 3px 3px; + border-color: hsla(0, 50%, 40%, .5); + border-radius: 5px 0 0 5px; +} +#message_close_button { + display: inline-block; + padding: 5px 10px; + background-color: hsl(0, 50%, 40%); + color: hsl(0, 90%, 90%); + border-style: solid; + border-width: 3px 3px 3px 0; + border-color: hsla(0, 50%, 30%, .5); + border-radius: 0 5px 5px 0; + cursor: pointer; +} + + +h1 { + margin: 5px 0 5px 0; + color: hsl(210, 50%, 50%); + font: bold 24px "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif; +} +h2 { + margin: 10px 0 2px 0; + color: hsl(0, 50%, 50%); + font: bold 20px "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif; +} + + +input[type=text].large { + display: inline-block; + width: 250px; + padding: 5px 10px; + border: 2px solid hsl(0, 0%, 80%); + border-radius: 3px; + height: 24px; + background: transparent; + font: normal 20px Tahoma, "Ubuntu Condensed"; + color: hsl(0, 0%, 20%); +} + +input[type=text].medium { + display: inline-block; + width: 175px; + padding: 2px 5px; + border: 2px solid hsl(0, 0%, 80%); + border-radius: 3px; + height: 20px; + background: transparent; + font: normal 18px Tahoma, "Ubuntu Condensed"; + color: hsl(0, 0%, 20%); +} + +input[placeholder] { + color: hsl(0, 0%, 50%); +} + + +#connect_panel { + background-color: hsl(210, 50%, 90%); + border-radius: 5px; + padding: 3px 10px; +} +#submit_button { + display: inline-block; + padding: 1px 5px; + background-color: hsl(210, 50%, 30%); + color: hsl(210, 0%, 100%); + border-radius: 3px; + cursor: pointer; +} + + +.dic_button { + margin: 2px; + display: inline-block; +} +.dic_button_close { + display: inline-block; + padding: 1px 5px; + background-color: hsl(0, 50%, 50%); + color: hsl(0, 90%, 90%); + border-style: solid; + border-width: 1px 0 1px 1px; + border-color: hsl(0, 50%, 45%); + border-radius: 3px 0 0 3px; + cursor: pointer; +} +.dic_button_label { + display: inline-block; + padding: 1px 10px; + background-color: hsl(210, 50%, 94%); + border-style: solid; + border-width: 1px 1px 1px 0; + border-color: hsl(210, 50%, 70%); + border-radius: 0 3px 3px 0; +} + +.apply { + display: none; + float: right; + padding: 2px 10px; + background: hsl(120, 50%, 30%); + color: hsl(120, 50%, 96%); + cursor: pointer; + border-radius: 3px; +} + + +/* + Table +*/ +#wait_progress { + width: 100%; + height: 4px; +} + +table { + border: 1px solid hsl(210, 10%, 50%); + width: 100%; + font-size: 14px; +} +th { + padding: 5px 10px; + border-left: 1px solid hsl(210, 10%, 90%); + text-align: left; +} +td { + padding: 0 10px; + vertical-align: top; +} +.delete_entry { + cursor: pointer; + font-weight: bold; + color: hsl(0, 100%, 50%); +} +.select_entry { + cursor: pointer; + background-color: hsl(210, 50%, 30%); + color: hsl(210, 50%, 100%); + border-radius: 3px; + text-align: center; +} ADDED gc_lang/fr/webext/panel/dictionaries.html Index: gc_lang/fr/webext/panel/dictionaries.html ================================================================== --- /dev/null +++ gc_lang/fr/webext/panel/dictionaries.html @@ -0,0 +1,57 @@ + + +
+ ++ Connecté. Identifiants : , +
+[Aucun]
+ +
Nombre d’entrées : 0.
-Il est déconseillé d’utiliser la catégorie ‹Autre› pour générer autre chose que des noms, des adjectifs, des noms propres, des verbes et des adverbes. Il n’y a aucune garantie que les étiquettes pour les autres catégories, notamment les mots grammaticaux, ne changeront pas.