Index: gc_lang/fr/config.ini ================================================================== --- gc_lang/fr/config.ini +++ gc_lang/fr/config.ini @@ -3,11 +3,11 @@ lang_name = French locales = fr_FR fr_BE fr_CA fr_CH fr_LU fr_MC fr_BF fr_CI fr_SN fr_ML fr_NE fr_TG fr_BJ country_default = FR name = Grammalecte implname = grammalecte -version = 0.5.18 +version = 0.6 author = Olivier R. provider = Dicollecte link = http://grammalecte.net description = Correcteur grammatical pour le français. extras = README_fr.txt Index: gc_lang/fr/webext/background.js ================================================================== --- gc_lang/fr/webext/background.js +++ gc_lang/fr/webext/background.js @@ -50,20 +50,25 @@ case "getOptions": case "getDefaultOptions": case "setOptions": case "setOption": console.log("OPTIONS"); - console.log(e.data[1]); + break; case "getListOfTokens": console.log("TOKENS"); - console.log(e.data[1]); - let xLxgTab = browser.tabs.create({ + if (typeof(dInfo.iReturnPort) === "number") { + let xPort = aConnx[dInfo.iReturnPort]; + xPort.postMessage(e.data); + } else { + console.log("[background] don’t know where to send results"); + console.log(e.data); + } + /*let xLxgTab = browser.tabs.create({ url: browser.extension.getURL("panel/lexicographer.html"), }); - xLxgTab.then(onCreated, onError); - break; + xLxgTab.then(onCreated, onError);*/ break; default: console.log("Unknown command: " + sActionDone); console.log(result); } Index: gc_lang/fr/webext/content_scripts/content_panels.css ================================================================== --- gc_lang/fr/webext/content_scripts/content_panels.css +++ gc_lang/fr/webext/content_scripts/content_panels.css @@ -27,11 +27,16 @@ .grammalecte_wrapper_button:hover { background-color: hsl(210, 50%, 55%); box-shadow: 0 0 1px 1px hsl(210, 50%, 20%); color: hsl(210, 0%, 100%); } - +.grammalecte_wrapper_toolbar { + display: flex; + justify-content: flex-end; + margin-top: 5px; + padding: 5px 10px; +} /* Panels */ .grammalecte_panel { @@ -96,10 +101,87 @@ height: calc(100% - 45px); /* panel height - title_bar */ overflow: auto; } +/* + Lexicographer +*/ +#grammalecte_lxg_panel_content { + padding: 10px; +} + +.grammalecte_lxg_list_of_tokens { + background-color: hsla(0, 0%, 90%, 1); + padding: 10px; + border-radius: 2px; + margin: 10px 5px; +} + +.grammalecte_token p { + margin: 8px; +} +.grammalecte_token p.separator { + margin: 20px 0; + padding: 5px 5px; + background-color: hsla(0, 0%, 75%, 1); + color: hsla(0, 0%, 96%, 1); + border-radius: 5px; + text-align: center; + font-size: 20px; +} +.grammalecte_token .token { + margin: 8px; +} +.grammalecte_token ul { + margin: 0 0 5px 40px; +} +.grammalecte_token b { + background-color: hsla(150, 10%, 50%, 1); + color: hsla(0, 0%, 96%, 1); + padding: 2px 5px; + border-radius: 2px; + text-decoration: none; +} +.grammalecte_token b.WORD { + background-color: hsla(150, 50%, 50%, 1); +} +.grammalecte_token b.ELPFX { + background-color: hsla(150, 30%, 50%, 1); +} +.grammalecte_token b.UNKNOWN { + background-color: hsla(0, 50%, 50%, 1); +} +.grammalecte_token b.NUM { + background-color: hsla(180, 50%, 50%, 1); +} +.grammalecte_token b.COMPLEX { + background-color: hsla(60, 50%, 50%, 1); +} +.grammalecte_token b.SEPARATOR { + background-color: hsla(210, 50%, 50%, 1); +} +.grammalecte_token b.LINK { + background-color: hsla(270, 50%, 50%, 1); +} +.grammalecte_token s { + color: hsla(0, 0%, 60%, 1); + text-decoration: none; +} +.grammalecte_token .textline { + text-decoration: bold; +} + +.grammalecte_token p.message { + margin-top: 20px; + padding: 10px 10px; + background-color: hsla(240, 10%, 50%, 1); + font-size: 18px; + color: hsla(240, 0%, 96%, 1); + border-radius: 3px; + text-align: center; +} /* Text Formatter */ #grammalecte_tf_options { ADDED gc_lang/fr/webext/content_scripts/gc_content.js Index: gc_lang/fr/webext/content_scripts/gc_content.js ================================================================== --- gc_lang/fr/webext/content_scripts/gc_content.js +++ gc_lang/fr/webext/content_scripts/gc_content.js @@ -0,0 +1,310 @@ +// JavaScript + +"use strict"; + +const oGCPanelContent = { + + _xContentNode: createNode("div", {id: "grammalecte_gc_panel_content"}), + + getNode: function () { + return this._xContentNode; + }, + + clear: function () { + while (this._xContentNode.firstChild) { + this._xContentNode.removeChild(this._xContentNode.firstChild); + } + }, + + addParagraphResult: function (sText, iId, oErrors) { + try { + let xNodeDiv = createNode("div", {className: "grammalecte_paragraph_block"}); + // actions + let xActionsBar = createNode("div", {className: "grammalecte_paragraph_actions"}); + let xCloseButton = createNode("div", {id: "end" + iId.toString(), className: "grammalecte_paragraph_close_button", textContent: "×"}); + let xAnalyseButton = createNode("div", {id: "check" + iId.toString(), className: "grammalecte_paragraph_analyse_button", textContent: "Réanalyser"}); + xActionsBar.appendChild(xAnalyseButton); + xActionsBar.appendChild(xCloseButton); + // paragraph + let xParagraph = createNode("p", {id: iId, lang: "fr", spellcheck: "false", contenteditable: "true"}); + xParagraph.className = (oErrors.aGrammErr.length || oErrors.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph"; + this._tagParagraph(sText, xParagraph, iParagraph, oErrors.aGrammErr, oErrors.aSpellErr); + // creation + xNodeDiv.appendChild(xActionsBar); + xNodeDiv.appendChild(xParagraph); + this._xContentNode.appendChild(xNodeDiv); + } + catch (e) { + showError(e); + } + }, + + refreshParagraph: function (sText, sId, oErrors) { + try { + let xParagraph = document.getElementById("paragr"+sIdParagr); + xParagraph.className = (oErrors.aGrammErr.length || oErrors.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph"; + xParagraph.textContent = ""; + this._tagParagraph(sText, xParagraph, iParagraph, oErrors.aGrammErr, oErrors.aSpellErr); + } + catch (e) { + showError(e); + } + }, + + _tagParagraph: function (sParagraph, xParagraph, iParagraph, aSpellErr, aGrammErr) { + try { + if (aGrammErr.length === 0 && aSpellErr.length === 0) { + xParagraph.textContent = sParagraph; + return + } + aGrammErr.push(...aSpellErr); + aGrammErr.sort(function (a, b) { + if (a["nStart"] < b["nStart"]) + return -1; + if (a["nStart"] > b["nStart"]) + return 1; + return 0; + }); + let nErr = 0; // we count errors to give them an identifier + let nEndLastErr = 0; + for (let oErr of aGrammErr) { + let nStart = oErr["nStart"]; + let nEnd = oErr["nEnd"]; + if (nStart >= nEndLastErr) { + oErr['sErrorId'] = iParagraph.toString() + "_" + nErr.toString(); // error identifier + oErr['sIgnoredKey'] = iParagraph.toString() + ":" + nStart.toString() + ":" + nEnd.toString() + ":" + sParagraph.slice(nStart, nEnd); + if (nEndLastErr < nStart) { + xParagraph.appendChild(document.createTextNode(sParagraph.slice(nEndLastErr, nStart))); + } + xParagraph.appendChild(this._createError(sParagraph.slice(nStart, nEnd), oErr)); + xParagraph.insertAdjacentHTML("beforeend", ""); + nEndLastErr = nEnd; + } + nErr += 1; + } + if (nEndLastErr <= sParagraph.length) { + xParagraph.appendChild(document.createTextNode(sParagraph.slice(nEndLastErr))); + } + } + catch (e) { + showError(e); + } + }, + + _createError: function (sUnderlined, oErr) { + let xNodeErr = document.createElement("u"); + xNodeErr.id = "err" + oErr['sErrorId']; + xNodeErr.textContent = sUnderlined; + xNodeErr.dataset.error_id = oErr['sErrorId']; + xNodeErr.dataset.ignored_key = oErr['sIgnoredKey']; + xNodeErr.dataset.error_type = (oErr['sType'] === "WORD") ? "spelling" : "grammar"; + if (xNodeErr.dataset.error_type === "grammar") { + xNodeErr.dataset.gc_message = oErr['sMessage']; + xNodeErr.dataset.gc_url = oErr['URL']; + if (xNodeErr.dataset.gc_message.includes(" #")) { + xNodeErr.dataset.line_id = oErr['sLineId']; + xNodeErr.dataset.rule_id = oErr['sRuleId']; + } + xNodeErr.dataset.suggestions = oErr["aSuggestions"].join("|"); + } + xNodeErr.className = (aIgnoredErrors.has(xNodeErr.dataset.ignored_key)) ? "ignored" : "error " + oErr['sType']; + return xNodeErr; + }, + + applySuggestion: function (sSuggId) { // sugg + try { + let sErrorId = document.getElementById(sSuggId).dataset.error_id; + let sIdParagr = sErrorId.slice(0, sErrorId.indexOf("_")); + startWaitIcon("paragr"+sIdParagr); + let xNodeErr = document.getElementById("err" + sErrorId); + xNodeErr.textContent = document.getElementById(sSuggId).textContent; + xNodeErr.className = "corrected"; + xNodeErr.removeAttribute("style"); + self.port.emit("correction", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr)); + this.hideAllTooltips(); + stopWaitIcon("paragr"+sIdParagr); + } + catch (e) { + showError(e); + } + }, + + ignoreError: function (sIgnoreButtonId) { // ignore + try { + //console.log("ignore button: " + sIgnoreButtonId + " // error id: " + document.getElementById(sIgnoreButtonId).dataset.error_id); + let xNodeErr = document.getElementById("err"+document.getElementById(sIgnoreButtonId).dataset.error_id); + aIgnoredErrors.add(xNodeErr.dataset.ignored_key); + xNodeErr.className = "ignored"; + xNodeErr.removeAttribute("style"); + this.hideAllTooltips(); + } + catch (e) { + showError(e); + } + }, + + showTooltip: function (sNodeErrorId) { // err + try { + this.hideAllTooltips(); + let xNodeErr = document.getElementById(sNodeErrorId); + let sTooltipId = (xNodeErr.dataset.error_type === "grammar") ? "gc_tooltip" : "sc_tooltip"; + let xNodeTooltip = document.getElementById(sTooltipId); + let xNodeTooltipArrow = document.getElementById(sTooltipId+"_arrow"); + let nLimit = nPanelWidth - 330; // paragraph width - tooltip width + xNodeTooltipArrow.style.top = (xNodeErr.offsetTop + 16) + "px" + xNodeTooltipArrow.style.left = (xNodeErr.offsetLeft + Math.floor((xNodeErr.offsetWidth / 2))-4) + "px" // 4 is half the width of the arrow. + xNodeTooltip.style.top = (xNodeErr.offsetTop + 20) + "px"; + xNodeTooltip.style.left = (xNodeErr.offsetLeft > nLimit) ? nLimit + "px" : xNodeErr.offsetLeft + "px"; + if (xNodeErr.dataset.error_type === "grammar") { + // grammar error + if (xNodeErr.dataset.gc_message.includes(" ##")) { + let n = xNodeErr.dataset.gc_message.indexOf(" ##"); + document.getElementById("gc_message").textContent = xNodeErr.dataset.gc_message.slice(0, n); + document.getElementById("gc_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2); + document.getElementById("gc_rule_id").style.display = "block"; + } else { + document.getElementById("gc_message").textContent = xNodeErr.dataset.gc_message; + } + if (xNodeErr.dataset.gc_url != "") { + document.getElementById("gc_url").style.display = "inline"; + document.getElementById("gc_url").setAttribute("href", xNodeErr.dataset.gc_url); + } else { + document.getElementById("gc_url").style.display = "none"; + } + document.getElementById("gc_ignore").dataset.error_id = xNodeErr.dataset.error_id; + let iSugg = 0; + let xGCSugg = document.getElementById("gc_sugg_block"); + xGCSugg.textContent = ""; + for (let sSugg of xNodeErr.dataset.suggestions.split("|")) { + xGCSugg.appendChild(this._createSuggestion(xNodeErr.dataset.error_id, iSugg, sSugg)); + xGCSugg.appendChild(document.createTextNode(" ")); + iSugg += 1; + } + } + xNodeTooltipArrow.style.display = "block"; + xNodeTooltip.style.display = "block"; + if (xNodeErr.dataset.error_type === "spelling") { + // spelling mistake + document.getElementById("sc_ignore").dataset.error_id = xNodeErr.dataset.error_id; + //console.log("getSuggFor: " + xNodeErr.textContent.trim() + " // error_id: " + xNodeErr.dataset.error_id); + self.port.emit("getSuggestionsForTo", xNodeErr.textContent.trim(), xNodeErr.dataset.error_id); + } + } + catch (e) { + showError(e); + } + }, + + _createSuggestion: function (sErrId, iSugg, sSugg) { + let xNodeSugg = document.createElement("a"); + xNodeSugg.id = "sugg" + sErrId + "-" + iSugg.toString(); + xNodeSugg.className = "sugg"; + xNodeSugg.dataset.error_id = sErrId; + xNodeSugg.textContent = sSugg; + return xNodeSugg; + }, + + setSpellSuggestionsFor: function (sWord, sSuggestions, sErrId) { + // spell checking suggestions + try { + // console.log("setSuggestionsFor: " + sWord + " > " + sSuggestions + " // " + sErrId); + let xSuggBlock = document.getElementById("sc_sugg_block"); + xSuggBlock.textContent = ""; + if (sSuggestions === "") { + xSuggBlock.appendChild(document.createTextNode("Aucune.")); + } else if (sSuggestions.startsWith("#")) { + xSuggBlock.appendChild(document.createTextNode(sSuggestions)); + } else { + let lSugg = sSuggestions.split("|"); + let iSugg = 0; + for (let sSugg of lSugg) { + xSuggBlock.appendChild(this._createSuggestion(sErrId, iSugg, sSugg)); + xSuggBlock.appendChild(document.createTextNode(" ")); + iSugg += 1; + } + } + } + catch (e) { + showError(e); + } + }, + + hideAllTooltips: function () { + document.getElementById("gc_tooltip").style.display = "none"; + document.getElementById("gc_rule_id").style.display = "none"; + document.getElementById("sc_tooltip").style.display = "none"; + document.getElementById("gc_tooltip_arrow").style.display = "none"; + document.getElementById("sc_tooltip_arrow").style.display = "none"; + }, + + addSummary: function () { + // todo + }, + + addMessage: function (sMessage) { + let xNode = createNode("div", {className: "grammalecte_gc_panel_message", textContent: sMessage}); + this._xContentNode.appendChild(xNode); + } +} + + + + + + + + + + + +function sendBackAndCheck (sCheckButtonId) { // check + startWaitIcon(); + let sIdParagr = sCheckButtonId.slice(5); + self.port.emit("modifyAndCheck", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr)); + stopWaitIcon(); +} + + + + + +function getPurgedTextOfParagraph (sNodeParagrId) { + let sText = document.getElementById(sNodeParagrId).textContent; + sText = sText.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); + return sText; +} + +function copyToClipboard () { + startWaitIcon(); + try { + let xClipboardButton = document.getElementById("clipboard_msg"); + xClipboardButton.textContent = "copie en cours…"; + let sText = ""; + for (let xNode of document.getElementById("errorlist").getElementsByClassName("paragraph")) { + sText += xNode.textContent + "\n"; + } + self.port.emit('copyToClipboard', sText); + xClipboardButton.textContent = "-> presse-papiers"; + window.setTimeout(function() { xClipboardButton.textContent = "∑"; } , 3000); + } + catch (e) { + console.log(e.lineNumber + ": " +e.message); + } + stopWaitIcon(); +} + +function startWaitIcon (sIdParagr=null) { + if (sIdParagr) { + document.getElementById(sIdParagr).disabled = true; + document.getElementById(sIdParagr).style.opacity = .3; + } + document.getElementById("waiticon").hidden = false; +} + +function stopWaitIcon (sIdParagr=null) { + if (sIdParagr) { + document.getElementById(sIdParagr).disabled = false; + document.getElementById(sIdParagr).style.opacity = 1; + } + document.getElementById("waiticon").hidden = true; +} ADDED gc_lang/fr/webext/content_scripts/lxg_content.js Index: gc_lang/fr/webext/content_scripts/lxg_content.js ================================================================== --- gc_lang/fr/webext/content_scripts/lxg_content.js +++ gc_lang/fr/webext/content_scripts/lxg_content.js @@ -0,0 +1,63 @@ +// JavaScript + +"use strict"; + +const oLxgPanelContent = { + + _xContentNode: createNode("div", {id: "grammalecte_lxg_panel_content"}), + + getNode: function () { + return this._xContentNode; + }, + + clear: function () { + while (this._xContentNode.firstChild) { + this._xContentNode.removeChild(this._xContentNode.firstChild); + } + }, + + addSeparator: function (sText) { + if (this._xContentNode.textContent !== "") { + this._xContentNode.appendChild(createNode("div", {className: "grammalecte_lxg_separator", textContent: sText})); + } + }, + + addMessage: function (sClass, sText) { + this._xContentNode.appendChild(createNode("div", {className: sClass, textContent: sText})); + }, + + addListOfTokens: function (lTokens) { + try { + let xNodeDiv = createNode("div", {className: "grammalecte_lxg_list_of_tokens"}); + for (let oToken of lTokens) { + xNodeDiv.appendChild(this._createTokenNode(oToken)); + } + this._xContentNode.appendChild(xNodeDiv); + } + catch (e) { + showError(e); + } + }, + + _createTokenNode: function (oToken) { + let xTokenNode = createNode("div", {className: "grammalecte_token " + oToken.sType}); + xTokenNode.appendChild(createNode("b", {className: oToken.sType, textContent: oToken.sValue})); + xTokenNode.appendChild(createNode("s", {textContent: " : "})); + if (oToken.aLabel.length === 1) { + xTokenNode.appendChild(document.createTextNode(oToken.aLabel[0])); + } else { + let xTokenList = document.createElement("ul"); + for (let sLabel of oToken.aLabel) { + xTokenList.appendChild(createNode("li", {textContent: sLabel})); + } + xTokenNode.appendChild(xTokenList); + } + return xTokenNode; + }, + + setHidden: function (sClass, bHidden) { + for (let xNode of document.getElementsByClassName(sClass)) { + xNode.hidden = bHidden; + } + } +} Index: gc_lang/fr/webext/content_scripts/modify_page.js ================================================================== --- gc_lang/fr/webext/content_scripts/modify_page.js +++ gc_lang/fr/webext/content_scripts/modify_page.js @@ -49,44 +49,33 @@ } } function createWrapperToolbar (xTextArea) { try { - let xToolbar = document.createElement("div"); - xToolbar.style = "display: flex; justify-content: flex-end; margin-top: 5px; padding: 5px 10px;"; - /*let xLogo = document.createElement("img"); - xLogo.src = browser.extension.getURL("img/logo-16.png"); // can’t work, due to content-script policy: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 - xTitle.appendChild(xLogo);*/ - - xToolbar.appendChild(document.createTextNode("Grammalecte")); - let xConjButton = document.createElement("div"); - xConjButton.textContent = "Conjuguer"; - xConjButton.className = "grammalecte_wrapper_button"; - xConjButton.onclick = function() { - createConjPanel(); - }; - xToolbar.appendChild(xConjButton); - let xTFButton = document.createElement("div"); - xTFButton.textContent = "Formater"; - xTFButton.className = "grammalecte_wrapper_button"; - xTFButton.onclick = function() { - createTFPanel(xTextArea); - }; - xToolbar.appendChild(xTFButton); - let xLxgButton = document.createElement("div"); - xLxgButton.textContent = "Analyser"; - xLxgButton.className = "grammalecte_wrapper_button"; + let xToolbar = createNode("div", {className: "grammalecte_wrapper_toolbar"}); + let xConjButton = createNode("div", {className: "grammalecte_wrapper_button", textContent: "Conjuguer"}); + xConjButton.onclick = function() { createConjPanel(); }; + let xTFButton = createNode("div", {className: "grammalecte_wrapper_button", textContent: "Formater"}); + xTFButton.onclick = function() { createTFPanel(xTextArea); }; + let xLxgButton = createNode("div", {className: "grammalecte_wrapper_button", textContent: "Analyser"}); xLxgButton.onclick = function() { createLxgPanel(xTextArea); + xPort.postMessage({sCommand: "getListOfTokens", dParam: {sText: xTextArea.value}, dInfo: {sTextAreaId: xTextArea.id}}); }; - xToolbar.appendChild(xLxgButton); - let xGCButton = document.createElement("div"); - xGCButton.textContent = "Corriger"; - xGCButton.className = "grammalecte_wrapper_button"; + let xGCButton = createNode("div", {className: "grammalecte_wrapper_button", textContent: "Corriger"}); xGCButton.onclick = function() { + createGCPanel(); xPort.postMessage({sCommand: "parseAndSpellcheck", dParam: {sText: xTextArea.value, sCountry: "FR", bDebug: false, bContext: false}, dInfo: {sTextAreaId: xTextArea.id}}); }; + // Create + //xToolbar.appendChild(createNode("img", {scr: browser.extension.getURL("img/logo-16.png")})); + // can’t work, due to content-script policy: https://bugzilla.mozilla.org/show_bug.cgi?id=1267027 + xToolbar.appendChild(createLogo()); + xToolbar.appendChild(document.createTextNode("Grammalecte")); + xToolbar.appendChild(xConjButton); + xToolbar.appendChild(xTFButton); + xToolbar.appendChild(xLxgButton); xToolbar.appendChild(xGCButton); return xToolbar; } catch (e) { showError(e); @@ -110,37 +99,43 @@ oTFPanel.show(); } else { // create the panel oTFPanel = new GrammalectePanel("grammalecte_tf_panel", "Formateur de texte", 800, 600, false); oTFPanel.logInnerHTML(); - oTFPanel.setContent(createTextFormatter(xTextArea)); + oTFPanel.setContentNode(createTextFormatter(xTextArea)); oTFPanel.insertIntoPage(); } } function createLxgPanel (xTextArea) { console.log("Lexicographe"); if (oLxgPanel !== null) { + oLxgPanelContent.clear(); oLxgPanel.show(); } else { // create the panel oLxgPanel = new GrammalectePanel("grammalecte_lxg_panel", "Lexicographe", 500, 700); + oLxgPanel.setContentNode(oLxgPanelContent.getNode()); oLxgPanel.insertIntoPage(); } } -function createGCPanel (oErrors) { +function createGCPanel () { console.log("Correction grammaticale"); if (oGCPanel !== null) { + oGCPanelContent.clear(); oGCPanel.show(); } else { // create the panel oGCPanel = new GrammalectePanel("grammalecte_gc_panel", "Correcteur", 500, 700); - oGCPanel.setContent(document.createTextNode(JSON.stringify(oErrors))); oGCPanel.insertIntoPage(); } } + +function updateGCPanel (oErrors) { + oGCPanel.setContentNode(document.createTextNode(JSON.stringify(oErrors))); +} /* Simple message */ @@ -167,14 +162,15 @@ console.log("[Content script] tab id: " + result); nTadId = result; break; case "parseAndSpellcheck": console.log(result); - createGCPanel(result); + updateGCPanel(result); break; case "getListOfTokens": console.log(result); + oLxgPanelContent.addListOfTokens(result); break; default: console.log("[Content script] Unknown command: " + sActionDone); } }); Index: gc_lang/fr/webext/content_scripts/panel_creator.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel_creator.js +++ gc_lang/fr/webext/content_scripts/panel_creator.js @@ -61,11 +61,11 @@ let xButton = createNode("div", {className: "grammalecte_close_button", textContent: "×", title: "Fermer la fenêtre"}); xButton.onclick = function () { this.hide(); }.bind(this); // better than writing “let that = this;” before the function? return xButton; } - setContent (xNode) { + setContentNode (xNode) { this.xContentNode.appendChild(xNode); } insertIntoPage () { document.body.appendChild(this.xPanelNode); DELETED gc_lang/fr/webext/content_scripts/text_formatter.js Index: gc_lang/fr/webext/content_scripts/text_formatter.js ================================================================== --- gc_lang/fr/webext/content_scripts/text_formatter.js +++ gc_lang/fr/webext/content_scripts/text_formatter.js @@ -1,167 +0,0 @@ -// JavaScript -// Text formatter - -"use strict"; - -function createTextFormatter (xTextArea) { - let xTFNode = document.createElement("div"); - try { - // Options - let xOptions = createNode("div", {id: "grammalecte_tf_options"}); - let xColumn1 = createNode("div", {className: "grammalecte_tf_column"}); - let xSSP = createFieldset("group_ssp", true, "Espaces surnuméraires"); - xSSP.appendChild(createOptionInputAndLabel("o_start_of_paragraph", true, "En début de paragraphe")); - xSSP.appendChild(createOptionInputAndLabel("o_end_of_paragraph", true, "En fin de paragraphe")); - xSSP.appendChild(createOptionInputAndLabel("o_between_words", true, "Entre les mots")); - xSSP.appendChild(createOptionInputAndLabel("o_before_punctuation", true, "Avant les points (.), les virgules (,)")); - xSSP.appendChild(createOptionInputAndLabel("o_within_parenthesis", true, "À l’intérieur des parenthèses")); - xSSP.appendChild(createOptionInputAndLabel("o_within_square_brackets", true, "À l’intérieur des crochets")); - xSSP.appendChild(createOptionInputAndLabel("o_within_quotation_marks", true, "À l’intérieur des guillemets “ et ”")); - let xSpace = createFieldset("group_space", true, "Espaces manquants"); - xSpace.appendChild(createOptionInputAndLabel("o_add_space_after_punctuation", true, "Après , ; : ? ! . …")); - xSpace.appendChild(createOptionInputAndLabel("o_add_space_around_hyphens", true, "Autour des tirets d’incise")); - let xNBSP = createFieldset("group_nbsp", true, "Espaces insécables"); - xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_punctuation", true, "Avant : ; ? et !")); - xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_within_quotation_marks", true, "Avec les guillemets « et »")); - xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_symbol", true, "Avant % ‰ € $ £ ¥ ˚C")); - xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_within_numbers", true, "À l’intérieur des nombres")); - xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_units", true, "Avant les unités de mesure")); - let xDelete = createFieldset("group_delete", true, "Suppressions"); - xDelete.appendChild(createOptionInputAndLabel("o_erase_non_breaking_hyphens", true, "Tirets conditionnels")); - let xColumn2 = createNode("div", {className: "grammalecte_tf_column"}); - let xTypo = createFieldset("group_typo", true, "Signes typographiques"); - xTypo.appendChild(createOptionInputAndLabel("o_ts_apostrophe", true, "Apostrophe (’)")); - xTypo.appendChild(createOptionInputAndLabel("o_ts_ellipsis", true, "Points de suspension (…)")); - xTypo.appendChild(createOptionInputAndLabel("o_ts_dash_middle", true, "Tirets d’incise :")); - xTypo.appendChild(createRadioBoxHyphens("hyphen1", "o_ts_m_dash_middle", "o_ts_n_dash_middle", false)); - xTypo.appendChild(createOptionInputAndLabel("o_ts_dash_start", true, "Tirets en début de paragraphe :")); - xTypo.appendChild(createRadioBoxHyphens("hyphen2", "o_ts_m_dash_start", "o_ts_n_dash_start", true)); - xTypo.appendChild(createOptionInputAndLabel("o_ts_quotation_marks", true, "Modifier les guillemets droits (\" et ')")); - xTypo.appendChild(createOptionInputAndLabel("o_ts_units", true, "Points médians des unités (N·m, Ω·m…)")); - xTypo.appendChild(createOptionInputAndLabel("o_ts_spell", true, "Ligatures (cœur…) et diacritiques (ça, État…)")); - xTypo.appendChild(createRadioBoxLigatures()); - xTypo.appendChild(createLigaturesSelection()); - let xMisc = createFieldset("group_misc", true, "Divers"); - xMisc.appendChild(createOptionInputAndLabel("o_ordinals_no_exponant", true, "Ordinaux (15e, XXIe…)")); - xMisc.appendChild(createOptionInputAndLabel("o_etc", true, "Et cætera, etc.")); - xMisc.appendChild(createOptionInputAndLabel("o_missing_hyphens", true, "Traits d’union manquants")); - xMisc.appendChild(createOptionInputAndLabel("o_ma_word", true, "Apostrophes manquantes")); - let xStruct = createFieldset("group_struct", false, "Restructuration [!]"); - xStruct.appendChild(createOptionInputAndLabel("o_remove_hyphens_at_end_of_paragraphs", false, "Enlever césures en fin de ligne/paragraphe [!]")); - xStruct.appendChild(createOptionInputAndLabel("o_merge_contiguous_paragraphs", false, "Fusionner les paragraphes contigus [!]")); - xColumn1.appendChild(xSSP); - xColumn1.appendChild(xSpace); - xColumn1.appendChild(xNBSP); - xColumn1.appendChild(xDelete); - xColumn2.appendChild(xTypo); - xColumn2.appendChild(xMisc); - xColumn2.appendChild(xStruct); - xOptions.appendChild(xColumn1); - xOptions.appendChild(xColumn2); - // Actions - let xActions = createNode("div", {id: "grammalecte_tf_actions"}); - xActions.appendChild(createNode("div", {id: "grammalecte_tf_reset", textContent: "Par défaut", className: "grammalecte_button", style: "background-color: hsl(210, 50%, 50%)"})); - xActions.appendChild(createNode("progress", {id: "grammalecte_tf_progressbar"})); - xActions.appendChild(createNode("span", {id: "grammalecte_tf_time_res"})); - xActions.appendChild(createNode("div", {id: "grammalecte_tf_apply", textContent: "Appliquer", className: "grammalecte_button", style: "background-color: hsl(180, 50%, 50%)"})); - //xActions.appendChild(createNode("div", {id: "grammalecte_infomsg", textContent: "blabla"})); - // create result - xTFNode.appendChild(xOptions); - xTFNode.appendChild(xActions); - } - catch (e) { - //console.error(e); - showError(e); - } - return xTFNode; -} - - -/* - Common options -*/ -function createFieldset (sId, bDefault, sLabel) { - let xFieldset = createNode("fieldset", {id: sId, className: "groupblock"}); - let xLegend = document.createElement("legend"); - xLegend.appendChild(createNode("input", {type: "checkbox", id: "o_"+sId, className: "option"}, {default: bDefault})); - xLegend.appendChild(createNode("label", {htmlFor: "o_"+sId, textContent: sLabel})); - xFieldset.appendChild(xLegend); - return xFieldset; -} - -function createOptionInputAndLabel (sId, bDefault, sLabel) { - let xOption = createNode("div", {className: "blockopt underline"}); - xOption.appendChild(createNode("input", {type: "checkbox", id: sId, className: "option"}, {default: bDefault})); - xOption.appendChild(createNode("label", {htmlFor: sId, textContent: sLabel, className: "opt_lbl largew"})); - xOption.appendChild(createNode("div", {id: "res_"+sId, className: "grammalecte_tf_result", textContent: "9999"})); - return xOption; -} - - -/* - Hyphens -*/ -function createRadioBoxHyphens (sName, sIdEmDash, sIdEnDash, bDefaultEmDash) { - let xLine = createNode("div", {className: "blockopt"}); - xLine.appendChild(createNode("input", {type: "radio", id: sIdEmDash, name: sName, className:"option"}, {default: bDefaultEmDash})); - xLine.appendChild(createNode("label", {htmlFor: sIdEmDash, className: "opt_lbl", textContent: "cadratin (—)"})); - xLine.appendChild(createNode("input", {type: "radio", id: sIdEnDash, name: sName, className:"option"}, {default: !bDefaultEmDash})); - xLine.appendChild(createNode("label", {htmlFor: sIdEnDash, className: "opt_lbl", textContent: "demi-cadratin (–)"})); - return xLine; -} - - -/* - Ligatures -*/ -function createRadioBoxLigatures () { - let xLine = createNode("div", {className: "blockopt underline"}); - xLine.appendChild(createOptionInputAndLabel("o_ts_ligature", true, "Ligatures")); - xLine.appendChild(createNode("input", {type: "radio", id: "o_ts_ligature_do", name: "liga", className:"option"}, {default: false})); - xLine.appendChild(createNode("label", {htmlFor: "o_ts_ligature_do", className: "opt_lbl", textContent: "faire"})); - xLine.appendChild(createNode("input", {type: "radio", id: "o_ts_ligature_undo", name: "liga", className:"option"}, {default: true})); - xLine.appendChild(createNode("label", {htmlFor: "o_ts_ligature_undo", className: "opt_lbl", textContent: "défaire"})); - return xLine; -} - -function createLigaturesSelection () { - let xLine = createNode("div", {className: "blockopt"}); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ff", "ff", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_fi", "fi", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ffi", "ffi", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_fl", "fl", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ffl", "ffl", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ft", "ft", true)); - xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_st", "st", false)); - return xLine; -} - -function createLigatureCheckboxAndLabel (sId, sLabel, bDefault) { - let xInlineBlock = createNode("div", {style: "display: inline-block;"}); - xInlineBlock.appendChild(createNode("input", {type: "checkbox", id: sId, className: "option"}, {default: bDefault})); - xInlineBlock.appendChild(createNode("label", {htmlFor: sId, className: "opt_lbl", textContent: sLabel})); - return xInlineBlock; -} - -let sTFinnerHTML = ' \ - \ -
\ -
\ - \ - \ -
\ - \ - \ -
\ -
\ -
\ -
\ - \ - \ -
\ -
\ - \ - \ -
\ -
\ -'; ADDED gc_lang/fr/webext/content_scripts/tf_content.js Index: gc_lang/fr/webext/content_scripts/tf_content.js ================================================================== --- gc_lang/fr/webext/content_scripts/tf_content.js +++ gc_lang/fr/webext/content_scripts/tf_content.js @@ -0,0 +1,167 @@ +// JavaScript +// Text formatter + +"use strict"; + +function createTextFormatter (xTextArea) { + let xTFNode = document.createElement("div"); + try { + // Options + let xOptions = createNode("div", {id: "grammalecte_tf_options"}); + let xColumn1 = createNode("div", {className: "grammalecte_tf_column"}); + let xSSP = createFieldset("group_ssp", true, "Espaces surnuméraires"); + xSSP.appendChild(createOptionInputAndLabel("o_start_of_paragraph", true, "En début de paragraphe")); + xSSP.appendChild(createOptionInputAndLabel("o_end_of_paragraph", true, "En fin de paragraphe")); + xSSP.appendChild(createOptionInputAndLabel("o_between_words", true, "Entre les mots")); + xSSP.appendChild(createOptionInputAndLabel("o_before_punctuation", true, "Avant les points (.), les virgules (,)")); + xSSP.appendChild(createOptionInputAndLabel("o_within_parenthesis", true, "À l’intérieur des parenthèses")); + xSSP.appendChild(createOptionInputAndLabel("o_within_square_brackets", true, "À l’intérieur des crochets")); + xSSP.appendChild(createOptionInputAndLabel("o_within_quotation_marks", true, "À l’intérieur des guillemets “ et ”")); + let xSpace = createFieldset("group_space", true, "Espaces manquants"); + xSpace.appendChild(createOptionInputAndLabel("o_add_space_after_punctuation", true, "Après , ; : ? ! . …")); + xSpace.appendChild(createOptionInputAndLabel("o_add_space_around_hyphens", true, "Autour des tirets d’incise")); + let xNBSP = createFieldset("group_nbsp", true, "Espaces insécables"); + xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_punctuation", true, "Avant : ; ? et !")); + xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_within_quotation_marks", true, "Avec les guillemets « et »")); + xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_symbol", true, "Avant % ‰ € $ £ ¥ ˚C")); + xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_within_numbers", true, "À l’intérieur des nombres")); + xNBSP.appendChild(createOptionInputAndLabel("o_nbsp_before_units", true, "Avant les unités de mesure")); + let xDelete = createFieldset("group_delete", true, "Suppressions"); + xDelete.appendChild(createOptionInputAndLabel("o_erase_non_breaking_hyphens", true, "Tirets conditionnels")); + let xColumn2 = createNode("div", {className: "grammalecte_tf_column"}); + let xTypo = createFieldset("group_typo", true, "Signes typographiques"); + xTypo.appendChild(createOptionInputAndLabel("o_ts_apostrophe", true, "Apostrophe (’)")); + xTypo.appendChild(createOptionInputAndLabel("o_ts_ellipsis", true, "Points de suspension (…)")); + xTypo.appendChild(createOptionInputAndLabel("o_ts_dash_middle", true, "Tirets d’incise :")); + xTypo.appendChild(createRadioBoxHyphens("hyphen1", "o_ts_m_dash_middle", "o_ts_n_dash_middle", false)); + xTypo.appendChild(createOptionInputAndLabel("o_ts_dash_start", true, "Tirets en début de paragraphe :")); + xTypo.appendChild(createRadioBoxHyphens("hyphen2", "o_ts_m_dash_start", "o_ts_n_dash_start", true)); + xTypo.appendChild(createOptionInputAndLabel("o_ts_quotation_marks", true, "Modifier les guillemets droits (\" et ')")); + xTypo.appendChild(createOptionInputAndLabel("o_ts_units", true, "Points médians des unités (N·m, Ω·m…)")); + xTypo.appendChild(createOptionInputAndLabel("o_ts_spell", true, "Ligatures (cœur…) et diacritiques (ça, État…)")); + xTypo.appendChild(createRadioBoxLigatures()); + xTypo.appendChild(createLigaturesSelection()); + let xMisc = createFieldset("group_misc", true, "Divers"); + xMisc.appendChild(createOptionInputAndLabel("o_ordinals_no_exponant", true, "Ordinaux (15e, XXIe…)")); + xMisc.appendChild(createOptionInputAndLabel("o_etc", true, "Et cætera, etc.")); + xMisc.appendChild(createOptionInputAndLabel("o_missing_hyphens", true, "Traits d’union manquants")); + xMisc.appendChild(createOptionInputAndLabel("o_ma_word", true, "Apostrophes manquantes")); + let xStruct = createFieldset("group_struct", false, "Restructuration [!]"); + xStruct.appendChild(createOptionInputAndLabel("o_remove_hyphens_at_end_of_paragraphs", false, "Enlever césures en fin de ligne/paragraphe [!]")); + xStruct.appendChild(createOptionInputAndLabel("o_merge_contiguous_paragraphs", false, "Fusionner les paragraphes contigus [!]")); + xColumn1.appendChild(xSSP); + xColumn1.appendChild(xSpace); + xColumn1.appendChild(xNBSP); + xColumn1.appendChild(xDelete); + xColumn2.appendChild(xTypo); + xColumn2.appendChild(xMisc); + xColumn2.appendChild(xStruct); + xOptions.appendChild(xColumn1); + xOptions.appendChild(xColumn2); + // Actions + let xActions = createNode("div", {id: "grammalecte_tf_actions"}); + xActions.appendChild(createNode("div", {id: "grammalecte_tf_reset", textContent: "Par défaut", className: "grammalecte_button", style: "background-color: hsl(210, 50%, 50%)"})); + xActions.appendChild(createNode("progress", {id: "grammalecte_tf_progressbar"})); + xActions.appendChild(createNode("span", {id: "grammalecte_tf_time_res"})); + xActions.appendChild(createNode("div", {id: "grammalecte_tf_apply", textContent: "Appliquer", className: "grammalecte_button", style: "background-color: hsl(180, 50%, 50%)"})); + //xActions.appendChild(createNode("div", {id: "grammalecte_infomsg", textContent: "blabla"})); + // create result + xTFNode.appendChild(xOptions); + xTFNode.appendChild(xActions); + } + catch (e) { + //console.error(e); + showError(e); + } + return xTFNode; +} + + +/* + Common options +*/ +function createFieldset (sId, bDefault, sLabel) { + let xFieldset = createNode("fieldset", {id: sId, className: "groupblock"}); + let xLegend = document.createElement("legend"); + xLegend.appendChild(createNode("input", {type: "checkbox", id: "o_"+sId, className: "option"}, {default: bDefault})); + xLegend.appendChild(createNode("label", {htmlFor: "o_"+sId, textContent: sLabel})); + xFieldset.appendChild(xLegend); + return xFieldset; +} + +function createOptionInputAndLabel (sId, bDefault, sLabel) { + let xOption = createNode("div", {className: "blockopt underline"}); + xOption.appendChild(createNode("input", {type: "checkbox", id: sId, className: "option"}, {default: bDefault})); + xOption.appendChild(createNode("label", {htmlFor: sId, textContent: sLabel, className: "opt_lbl largew"})); + xOption.appendChild(createNode("div", {id: "res_"+sId, className: "grammalecte_tf_result", textContent: "9999"})); + return xOption; +} + + +/* + Hyphens +*/ +function createRadioBoxHyphens (sName, sIdEmDash, sIdEnDash, bDefaultEmDash) { + let xLine = createNode("div", {className: "blockopt"}); + xLine.appendChild(createNode("input", {type: "radio", id: sIdEmDash, name: sName, className:"option"}, {default: bDefaultEmDash})); + xLine.appendChild(createNode("label", {htmlFor: sIdEmDash, className: "opt_lbl", textContent: "cadratin (—)"})); + xLine.appendChild(createNode("input", {type: "radio", id: sIdEnDash, name: sName, className:"option"}, {default: !bDefaultEmDash})); + xLine.appendChild(createNode("label", {htmlFor: sIdEnDash, className: "opt_lbl", textContent: "demi-cadratin (–)"})); + return xLine; +} + + +/* + Ligatures +*/ +function createRadioBoxLigatures () { + let xLine = createNode("div", {className: "blockopt underline"}); + xLine.appendChild(createOptionInputAndLabel("o_ts_ligature", true, "Ligatures")); + xLine.appendChild(createNode("input", {type: "radio", id: "o_ts_ligature_do", name: "liga", className:"option"}, {default: false})); + xLine.appendChild(createNode("label", {htmlFor: "o_ts_ligature_do", className: "opt_lbl", textContent: "faire"})); + xLine.appendChild(createNode("input", {type: "radio", id: "o_ts_ligature_undo", name: "liga", className:"option"}, {default: true})); + xLine.appendChild(createNode("label", {htmlFor: "o_ts_ligature_undo", className: "opt_lbl", textContent: "défaire"})); + return xLine; +} + +function createLigaturesSelection () { + let xLine = createNode("div", {className: "blockopt"}); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ff", "ff", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_fi", "fi", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ffi", "ffi", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_fl", "fl", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ffl", "ffl", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_ft", "ft", true)); + xLine.appendChild(createLigatureCheckboxAndLabel("o_ts_ligature_st", "st", false)); + return xLine; +} + +function createLigatureCheckboxAndLabel (sId, sLabel, bDefault) { + let xInlineBlock = createNode("div", {style: "display: inline-block;"}); + xInlineBlock.appendChild(createNode("input", {type: "checkbox", id: sId, className: "option"}, {default: bDefault})); + xInlineBlock.appendChild(createNode("label", {htmlFor: sId, className: "opt_lbl", textContent: sLabel})); + return xInlineBlock; +} + +let sTFinnerHTML = ' \ + \ +
\ +
\ + \ + \ +
\ + \ + \ +
\ +
\ +
\ +
\ + \ + \ +
\ +
\ + \ + \ +
\ +
\ +'; Index: gc_lang/fr/webext/manifest.json ================================================================== --- gc_lang/fr/webext/manifest.json +++ gc_lang/fr/webext/manifest.json @@ -38,11 +38,13 @@ { "matches": [""], "css": ["content_scripts/content_panels.css"], "js": [ "content_scripts/panel_creator.js", - "content_scripts/text_formatter.js", + "content_scripts/tf_content.js", + "content_scripts/gc_content.js", + "content_scripts/lxg_content.js", "content_scripts/modify_page.js" ] } ], "web_accessible_resources": [ Index: gc_lang/fr/xpi/package.json ================================================================== --- gc_lang/fr/xpi/package.json +++ gc_lang/fr/xpi/package.json @@ -1,10 +1,10 @@ { "name": "grammalecte-fr", "title": "Grammalecte [fr]", "id": "French-GC@grammalecte.net", - "version": "0.5.18", + "version": "0.5.19", "description": "Correcteur grammatical pour le français", "homepage": "http://www.dicollecte.org/grammalecte", "main": "ui.js", "icon": "data/img/icon-48.png", "scripts": {