Index: gc_lang/fr/webext/background.js ================================================================== --- gc_lang/fr/webext/background.js +++ gc_lang/fr/webext/background.js @@ -19,10 +19,11 @@ case "init": console.log("INIT DONE"); break; case "parse": case "parseAndSpellcheck": + case "parseAndSpellcheck1": case "getListOfTokens": console.log("Action done: " + sActionDone); if (typeof(dInfo.iReturnPort) === "number") { let xPort = aConnx[dInfo.iReturnPort]; xPort.postMessage(e.data); @@ -74,19 +75,22 @@ console.log("[background] received:"); console.log(oRequest); switch (oRequest.sCommand) { case "parse": case "parseAndSpellcheck": + case "parseAndSpellcheck1": case "getListOfTokens": case "textToTest": case "getOptions": case "getDefaultOptions": case "setOptions": case "setOption": case "fullTests": xGCEWorker.postMessage(oRequest); break; + default: + console.log("[background] Unknown command: " + oRequest.sCommand); } //sendResponse({response: "response from background script"}); } browser.runtime.onMessage.addListener(handleMessage); @@ -104,10 +108,11 @@ case "getCurrentTabId": xPort.postMessage({sActionDone: "getCurrentTabId", result: "getCurrentTabId()", dInfo: null, bError: false}); break; case "parse": case "parseAndSpellcheck": + case "parseAndSpellcheck1": case "getListOfTokens": oRequest.dInfo.iReturnPort = iPortId; // we pass the id of the return port to receive answer console.log(oRequest); xGCEWorker.postMessage(oRequest); break; Index: gc_lang/fr/webext/content_scripts/content_modifier.js ================================================================== --- gc_lang/fr/webext/content_scripts/content_modifier.js +++ gc_lang/fr/webext/content_scripts/content_modifier.js @@ -57,16 +57,24 @@ 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(); - xPort.postMessage({sCommand: "getListOfTokens", dParam: {sText: xTextArea.value}, dInfo: {sTextAreaId: xTextArea.id}}); + xPort.postMessage({ + sCommand: "getListOfTokens", + dParam: {sText: xTextArea.value}, + dInfo: {sTextAreaId: xTextArea.id} + }); }; 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}}); + 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()); @@ -146,35 +154,45 @@ browser.runtime.onMessage.addListener(handleMessage); /* - Connexion + Connexion to the background */ let xPort = browser.runtime.connect({name: "content-script port"}); + xPort.onMessage.addListener(function (oMessage) { console.log("[Content script] received…"); let {sActionDone, result, dInfo, bError} = oMessage; switch (sActionDone) { case "getCurrentTabId": console.log("[Content script] tab id: " + result); nTadId = result; break; case "parseAndSpellcheck": - console.log(result); + console.log("[content script] received: parseAndSpellcheck"); oGCPanelContent.addParagraphResult(result); break; + case "parseAndSpellcheck1": + console.log("[content script] received: parseAndSpellcheck1"); + oGCPanelContent.refreshParagraph(dInfo.sParagraphId, result); + break; case "getListOfTokens": - console.log(result); + console.log("[content script] received: getListOfTokens"); oLxgPanelContent.addListOfTokens(result); break; default: console.log("[Content script] Unknown command: " + sActionDone); } }); -xPort.postMessage({sCommand: "getCurrentTabId", dParam: {}, dInfo: {}}); + +xPort.postMessage({ + sCommand: "getCurrentTabId", + dParam: {}, + dInfo: {} +}); /*document.body.addEventListener("click", function () { xPort.postMessage({greeting: "they clicked the page!"}); });*/ wrapTextareas(); Index: gc_lang/fr/webext/content_scripts/gc_content.css ================================================================== --- gc_lang/fr/webext/content_scripts/gc_content.css +++ gc_lang/fr/webext/content_scripts/gc_content.css @@ -79,17 +79,18 @@ /* Action buttons */ .grammalecte_actions { + float: right; margin: 0 0 5px 10px; } .grammalecte_actions .button { + display: inline-block; background-color: hsl(0, 0%, 50%); text-align: center; - float: right; margin-left: 2px; padding: 1px 4px 3px 4px; cursor: pointer; font-size: 14px; color: hsl(0, 0%, 96%); 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 @@ -4,22 +4,22 @@ function onGrammalecteGCPanelClick (xEvent) { try { let xElem = xEvent.target; if (xElem.id) { - if (xElem.id.startsWith("sugg")) { + if (xElem.id.startsWith("grammalecte_sugg")) { oGCPanelContent.applySuggestion(xElem.id); - } else if (xElem.id.endsWith("_ignore")) { + } else if (xElem.id === "grammalecte_tooltip_ignore") { oGCPanelContent.ignoreError(xElem.id); } else if (xElem.id.startsWith("grammalecte_check")) { - oGCPanelContent.recheckParagraph(xElem.id); - } else if (xElem.id.startsWith("grammalecte_end")) { + oGCPanelContent.recheckParagraph(xElem.id.slice(17)); + } else if (xElem.id.startsWith("grammalecte_hide")) { document.getElementById(xElem.id).parentNode.parentNode.style.display = "none"; - } else if (xElem.tagName === "U" && xElem.id.startsWith("err") + } else if (xElem.tagName === "U" && xElem.id.startsWith("grammalecte_err") && xElem.className !== "corrected" && xElem.className !== "ignored") { oGrammalecteTooltip.show(xElem.id); - } else if (xElem.id === "gc_url") { + } else if (xElem.id === "grammalecte_tooltip_url") { oGCPanelContent.openURL(xElem.getAttribute("href")); } else { oGrammalecteTooltip.hide(); } } else if (xElem.tagName === "A") { @@ -33,10 +33,18 @@ } } const oGCPanelContent = { + /* + KEYS for identifiers: + grammalecte_paragraph{Id} : [paragraph number] + grammalecte_check{Id} : [paragraph number] + grammalecte_hide{Id} : [paragraph number] + grammalecte_error{Id} : [paragraph number]-[error_number] + grammalecte_sugg{Id} : [paragraph number]-[error_number]--[suggestion_number] + */ bInitDone: false, xContentNode: null, xParagraphList: null, @@ -59,29 +67,21 @@ this.xParagraphList.removeChild(this.xParagraphList.firstChild); } this.aIgnoredErrors.clear(); }, - recheckParagraph: function (sCheckButtonId) { // check - //startWaitIcon(); - let sIdParagr = sCheckButtonId.slice(5); - self.port.emit("modifyAndCheck", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr)); - //stopWaitIcon(); - }, - addParagraphResult: function (oResult) { try { if (oResult) { let xNodeDiv = createNode("div", {className: "grammalecte_paragraph_block"}); // actions let xActionsBar = createNode("div", {className: "grammalecte_actions"}); - let xAnalyseButton = createNode("div", {id: "grammalecte_check" + oResult.sParaNum, className: "button green", textContent: "Réanalyser"}); - let xCloseButton = createNode("div", {id: "grammalecte_end" + oResult.sParaNum, className: "button red blod", textContent: "×"}); - xActionsBar.appendChild(xAnalyseButton); - xActionsBar.appendChild(xCloseButton); + xActionsBar.appendChild(createNode("div", {id: "grammalecte_check" + oResult.sParaNum, className: "button green", textContent: "Réanalyser"})); + xActionsBar.appendChild(createNode("div", {id: "grammalecte_hide" + oResult.sParaNum, className: "button red bold", textContent: "×"})); // paragraph - let xParagraph = createNode("p", {id: "paragr"+oResult.sParaNum, lang: "fr", spellcheck: "false", contenteditable: "true"}); + let xParagraph = createNode("p", {id: "grammalecte_paragraph"+oResult.sParaNum, lang: "fr", contentEditable: "true"}); + xParagraph.setAttribute("spellcheck", "false"); // doesn’t seem possible to use “spellcheck” as a common attribute. xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph"; this._tagParagraph(xParagraph, oResult.sParagraph, oResult.sParaNum, oResult.aGrammErr, oResult.aSpellErr); // creation xNodeDiv.appendChild(xActionsBar); xNodeDiv.appendChild(xParagraph); @@ -91,16 +91,28 @@ catch (e) { showError(e); } }, - refreshParagraph: function (oResult) { + recheckParagraph: function (sParagraphNum) { + //startWaitIcon(); + let sParagraphId = "grammalecte_paragraph" + sParagraphNum; + let xParagraph = document.getElementById(sParagraphId); + xPort.postMessage({ + sCommand: "parseAndSpellcheck1", + dParam: {sText: this.getPurgedTextOfParagraph(xParagraph.textContent), sCountry: "FR", bDebug: false, bContext: false}, + dInfo: {sParagraphId: sParagraphId} + }); + //stopWaitIcon(); + }, + + refreshParagraph: function (sParagraphId, oResult) { try { - let xParagraph = document.getElementById("paragr"+sIdParagr); + let xParagraph = document.getElementById(sParagraphId); xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph"; xParagraph.textContent = ""; - this._tagParagraph(xParagraph, oResult.sParagraph, oResult.sParaNum, oResult.aGrammErr, oResult.aSpellErr); + this._tagParagraph(xParagraph, oResult.sParagraph, sParagraphId.slice(21), oResult.aGrammErr, oResult.aSpellErr); } catch (e) { showError(e); } }, @@ -123,12 +135,12 @@ let nEndLastErr = 0; for (let oErr of aGrammErr) { let nStart = oErr["nStart"]; let nEnd = oErr["nEnd"]; if (nStart >= nEndLastErr) { - oErr['sErrorId'] = sParaNum + "_" + nErr.toString(); // error identifier - oErr['sIgnoredKey'] = sParaNum + ":" + nStart.toString() + ":" + nEnd.toString() + ":" + sParagraph.slice(nStart, nEnd); + oErr['sErrorId'] = sParaNum + "-" + nErr.toString(); // error identifier + oErr['sIgnoredKey'] = sParaNum + ":" + nStart.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", ""); @@ -145,11 +157,11 @@ } }, _createError: function (sUnderlined, oErr) { let xNodeErr = document.createElement("u"); - xNodeErr.id = "err" + oErr['sErrorId']; + xNodeErr.id = "grammalecte_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") { @@ -163,39 +175,45 @@ } xNodeErr.className = (this.aIgnoredErrors.has(xNodeErr.dataset.ignored_key)) ? "ignored" : "error " + oErr['sType']; return xNodeErr; }, - applySuggestion: function (sSuggId) { // sugg + applySuggestion: function (sNodeSuggId) { // sugg try { - let sErrorId = document.getElementById(sSuggId).dataset.error_id; - let sIdParagr = sErrorId.slice(0, sErrorId.indexOf("_")); - let xNodeErr = document.getElementById("err" + sErrorId); - xNodeErr.textContent = document.getElementById(sSuggId).textContent; + console.log(sNodeSuggId); + let sErrorId = document.getElementById(sNodeSuggId).dataset.error_id; + //let sParaNum = sErrorId.slice(0, sErrorId.indexOf("-")); + console.log("grammalecte_err"+sErrorId); + let xNodeErr = document.getElementById("grammalecte_err" + sErrorId); + xNodeErr.textContent = document.getElementById(sNodeSuggId).textContent; xNodeErr.className = "corrected"; xNodeErr.removeAttribute("style"); - //self.port.emit("correction", sIdParagr, getPurgedTextOfParagraph("paragr"+sIdParagr)); oGrammalecteTooltip.hide(); } 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); + console.log(sIgnoreButtonId); + let sErrorId = document.getElementById(sIgnoreButtonId).dataset.error_id; + console.log("grammalecte_err"+sErrorId); + let xNodeErr = document.getElementById("grammalecte_err" + sErrorId); this.aIgnoredErrors.add(xNodeErr.dataset.ignored_key); xNodeErr.className = "ignored"; - xNodeErr.removeAttribute("style"); oGrammalecteTooltip.hide(); } catch (e) { showError(e); } }, + + getPurgedTextOfParagraph: function (sText) { + return sText.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); + }, addSummary: function () { // todo }, @@ -205,14 +223,14 @@ }, copyToClipboard: function () { startWaitIcon(); try { - let xClipboardButton = document.getElementById("clipboard_msg"); + let xClipboardButton = document.getElementById("grammalecte_clipboard_button"); xClipboardButton.textContent = "copie en cours…"; let sText = ""; - for (let xNode of document.getElementById("errorlist").getElementsByClassName("paragraph")) { + for (let xNode of document.getElementById("grammalecte_paragraph_list").getElementsByClassName("grammalecte_paragraph")) { sText += xNode.textContent + "\n"; } self.port.emit('copyToClipboard', sText); xClipboardButton.textContent = "-> presse-papiers"; window.setTimeout(function() { xClipboardButton.textContent = "∑"; } , 3000); @@ -223,16 +241,10 @@ stopWaitIcon(); } } -function getPurgedTextOfParagraph (sNodeParagrId) { - let sText = document.getElementById(sNodeParagrId).textContent; - sText = sText.replace(/ /g, " ").replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); - return sText; -} - const oGrammalecteTooltip = { xTooltip: null, @@ -324,11 +336,11 @@ this.xTooltip.style.display = "none"; }, _createSuggestion: function (sErrId, iSugg, sSugg) { let xNodeSugg = document.createElement("a"); - xNodeSugg.id = "sugg" + sErrId + "-" + iSugg.toString(); + xNodeSugg.id = "grammalecte_sugg" + sErrId + "--" + iSugg.toString(); xNodeSugg.className = "sugg"; xNodeSugg.dataset.error_id = sErrId; xNodeSugg.textContent = sSugg; return xNodeSugg; }, Index: gc_lang/fr/webext/gce_worker.js ================================================================== --- gc_lang/fr/webext/gce_worker.js +++ gc_lang/fr/webext/gce_worker.js @@ -95,10 +95,12 @@ parse(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo); break; case "parseAndSpellcheck": parseAndSpellcheck(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo); break; + case "parseAndSpellcheck1": + parseAndSpellcheck1(dParam.sText, dParam.sCountry, dParam.bDebug, dParam.bContext, dInfo); case "getOptions": getOptions(dInfo); break; case "getDefaultOptions": getDefaultOptions(dInfo); @@ -193,10 +195,16 @@ n += 1; postMessage(createResponse("parseAndSpellcheck", {sParagraph: sParagraph, sParaNum: n.toString(), aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo, false)); } postMessage(createResponse("parseAndSpellcheck", null, dInfo, true)); } + +function parseAndSpellcheck1 (sParagraph, sCountry, bDebug, bContext, dInfo={}) { + let aGrammErr = gc_engine.parse(sParagraph, sCountry, bDebug, bContext); + let aSpellErr = oTokenizer.getSpellingErrors(sParagraph, oDict); + postMessage(createResponse("parseAndSpellcheck1", {sParagraph: sParagraph, aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo, true)); +} function getOptions (dInfo={}) { postMessage(createResponse("getOptions", gc_engine.getOptions().gl_toString(), dInfo, true)); }