Index: gc_lang/fr/webext/background.js ================================================================== --- gc_lang/fr/webext/background.js +++ gc_lang/fr/webext/background.js @@ -91,19 +91,22 @@ getTimeSinceLastResponse: function () { // result in seconds return Math.floor((Date.now() - this.nLastTimeWorkerResponse) / 1000); }, - restart: function () { - if (this.getTimeSinceLastResponse() <= 5) { + restart: function (nDelay=5) { + if (this.getTimeSinceLastResponse() <= nDelay) { + console.log("Worker not restarted. Worked ", nDelay, " seconds ago."); return false; } if (this.xGCEWorker) { this.xGCEWorker.terminate(); } this.start(); oInitHandler.initGrammarChecker(); + sendCommandToAllTabs("workerRestarted"); + console.log("Worker restarted."); return true; }, addTask: function () { // @@ -245,10 +248,13 @@ case "fullTests": case "setDictionary": case "setDictionaryOnOff": oWorkerHandler.xGCEWorker.postMessage(oRequest); break; + case "restartWorker": + oWorkerHandler.restart(dParam["nDelayLimit"]); + break; case "openURL": browser.tabs.create({url: dParam.sURL}); break; case "openConjugueurTab": openConjugueurTab(); @@ -284,10 +290,13 @@ case "getSpellSuggestions": case "getVerb": oRequest.dInfo.iReturnPort = iPortId; // we pass the id of the return port to receive answer oWorkerHandler.xGCEWorker.postMessage(oRequest); break; + case "restartWorker": + oWorkerHandler.restart(dParam["nDelayLimit"]); + break; case "openURL": browser.tabs.create({url: dParam.sURL}); break; case "openConjugueurTab": openConjugueurTab(); @@ -440,10 +449,16 @@ console.log(xTab); browser.tabs.sendMessage(xTab.id, {sActionRequest: sCommand}); } }, showError); } + +function sendCommandToAllTabs (sCommand) { + for (let [iTab, xTabPort] of dConnx.entries()) { + xTabPort.postMessage({sActionDone: sCommand, result: null, dInfo: null, bEnd: false, bError: false}); + } +} function openLexiconEditor (sName="__personal__") { if (nTabLexiconEditor === null) { if (bChrome) { browser.tabs.create({ 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 @@ -301,10 +301,11 @@ case "parseAndSpellcheck": if (!bEnd) { oGrammalecte.oGCPanel.addParagraphResult(result); } else { oGrammalecte.oGCPanel.stopWaitIcon(); + oGrammalecte.oGCPanel.endTimer(); } break; case "parseAndSpellcheck1": oGrammalecte.oGCPanel.refreshParagraph(dInfo.sParagraphId, result); break; @@ -314,10 +315,11 @@ case "getListOfTokens": if (!bEnd) { oGrammalecte.oGCPanel.addListOfTokens(result); } else { oGrammalecte.oGCPanel.stopWaitIcon(); + oGrammalecte.oGCPanel.endTimer(); } break; case "getSpellSuggestions": oGrammalecte.oGCPanel.oTooltip.setSpellSuggestionsFor(result.sWord, result.aSugg, result.iSuggBlock, dInfo.sErrorId); break; @@ -326,10 +328,14 @@ oGrammalecte.oGCPanel.conjugateWith(result.oVerb, result.oConjTable); } else { oGrammalecte.oGCPanel.displayConj(result.oConjTable); } break; + case "workerRestarted": + oGrammalecte.oGCPanel.stopWaitIcon(); + oGrammalecte.oGCPanel.showMessage("Le serveur grammatical a été arrêté et relancé."); + break; /* Commands received from the context menu (Context menu are initialized in background) */ // Grammar checker commands Index: gc_lang/fr/webext/content_scripts/panel.css ================================================================== --- gc_lang/fr/webext/content_scripts/panel.css +++ gc_lang/fr/webext/content_scripts/panel.css @@ -176,10 +176,24 @@ border-color: hsl(60, 90%, 50%); color: hsl(60, 10%, 40%); font-family: "Trebuchet MS", "Fira Sans", "Ubuntu Condensed", "Liberation Sans", sans-serif; font-size: 14px; hyphens: auto; +} +div#grammalecte_panel_message_action_button { + margin: 10px; + padding: 4px 10px; + border-radius: 5px; + background-color: hsl(30, 100%, 50%); + color: hsl(30, 60%, 95%); + font-size: 14px; + font-weight: bold; + cursor: pointer; +} +div#grammalecte_panel_message_close_button:hover { + background-color: hsl(0, 100%, 60%); + color: hsl(0, 50%, 100%); } div#grammalecte_panel_message_close_button { float: right; margin: 0 0 10px 10px; padding: 2px 5px; Index: gc_lang/fr/webext/content_scripts/panel.js ================================================================== --- gc_lang/fr/webext/content_scripts/panel.js +++ gc_lang/fr/webext/content_scripts/panel.js @@ -114,11 +114,13 @@ this.xPanelMessageBlock = oGrammalecte.createNode("div", {id: "grammalecte_panel_message_block"}); let xPanelMessageCloseButton = oGrammalecte.createNode("div", {id: "grammalecte_panel_message_close_button", textContent: "×"}); xPanelMessageCloseButton.onclick = () => { this.hideMessage() }; this.xPanelMessageBlock.appendChild(xPanelMessageCloseButton); this.xPanelMessage = oGrammalecte.createNode("div", {id: "grammalecte_panel_message"}); + this.xPanelMessageActionButton = oGrammalecte.createNode("div", {id: "grammalecte_panel_message_action_button"}); this.xPanelMessageBlock.appendChild(this.xPanelMessage); + this.xPanelMessageBlock.appendChild(this.xPanelMessageActionButton); } insertIntoPage () { if (this.bShadow) { oGrammalecte.createStyle("content_scripts/panel.css", null, this.xShadow); @@ -247,17 +249,42 @@ stopWaitIcon () { this.bWorking = false; this.xWaitIcon.style.visibility = "hidden"; } - showMessage (sMessage) { + showMessage (sMessage, sActionMessage="", sActionName="") { this.xPanelMessageBlock.style.display = "block"; this.xPanelMessage.textContent = sMessage; + if (sActionMessage) { + this.xPanelMessageActionButton.textContent = sActionMessage; + this.xPanelMessageActionButton.style.display = "block"; + this.xPanelMessageActionButton.onclick = () => { this.executeButtonAction(sActionName); }; + } else { + this.xPanelMessageActionButton.style.display = "none"; + } } hideMessage () { this.xPanelMessageBlock.style.display = "none"; + this.xPanelMessageActionButton.style.display = "none"; + } + + executeButtonAction (sActionName) { + switch (sActionName) { + case "": + break; + case "restartWorker": + xGrammalectePort.postMessage({ + sCommand: "restartWorker", + dParam: { "nTimeDelay": 10 }, + dInfo: {} + }); + this.stopWaitIcon(); + break; + default: + console.log("Action inconnue: ", sAction); + } } openURL (sURL) { xGrammalectePort.postMessage({ sCommand: "openURL", 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 @@ -60,10 +60,11 @@ this.oTooltip = new GrammalecteTooltip(this.xParent, this.xGCPanelContent); this.xPanelContent.appendChild(this.xGCPanelContent); this.xNode = null; this.oTextControl = new GrammalecteTextControl(); this.bAutoRefresh = false; + this.nLastResult = 0 // Lexicographer this.nLxgCount = 0; this.xLxgPanelContent = oGrammalecte.createNode("div", {id: "grammalecte_lxg_panel_content"}); this.xPanelContent.appendChild(this.xLxgPanelContent); // Conjugueur @@ -137,10 +138,11 @@ start (what) { this.oTooltip.hide(); this.bWorking = false; this.clear(); this.hideMessage(); + this.resetTimer(); if (typeof(what) === "string") { // text this.xNode = null; this.oTextControl.setText(what); } else if (what.nodeType && what.nodeType === 1) { @@ -157,10 +159,11 @@ recheckAll () { this.oTooltip.hide(); this.showEditor(); this.clear(); this.startWaitIcon(); + this.resetTimer(); xGrammalectePort.postMessage({ sCommand: "parseAndSpellcheck", dParam: {sText: this.oTextControl.getText(), sCountry: "FR", bDebug: false, bContext: false}, dInfo: ((this.xNode) ? {sTextAreaId: this.xNode.id} : {}) }); @@ -218,10 +221,11 @@ this.oTextControl.clear(); } addParagraphResult (oResult) { try { + this.resetTimer(); if (oResult && (oResult.sParagraph.trim() !== "" || oResult.aGrammErr.length > 0 || oResult.aSpellErr.length > 0)) { let xNodeDiv = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_block"}); // actions let xActionsBar = oGrammalecte.createNode("div", {className: "grammalecte_paragraph_actions"}); xActionsBar.appendChild(oGrammalecte.createNode("div", {id: "grammalecte_check" + oResult.iParaNum, className: "grammalecte_paragraph_button grammalecte_green", textContent: "↻", title: "Réanalyser…"}, {para_num: oResult.iParaNum})); @@ -264,10 +268,26 @@ } catch (e) { showError(e); } } + + resetTimer () { + this.nLastResult = Date.now(); + window.clearTimeout(this.nTimer); + this.nTimer = window.setTimeout( + oGrammalecte.oGCPanel.showMessage.bind(this), + 5000, + "Le serveur grammatical semble ne plus répondre.", + "Arrêter et relancer le serveur grammatical.", + "restartWorker" + ); + } + + endTimer () { + window.clearTimeout(this.nTimer); + } recheckParagraph (iParaNum) { let sParagraphId = "grammalecte_paragraph" + iParaNum; let xParagraph = this.xParent.getElementById(sParagraphId); this.blockParagraph(xParagraph); Index: gc_lang/fr/webext/panel/main.html ================================================================== --- gc_lang/fr/webext/panel/main.html +++ gc_lang/fr/webext/panel/main.html @@ -155,10 +155,11 @@

ZONE DE TEST

Section de contrôle pour le développement du logiciel…

+
Redémarrer le worker
Tests complets
Analyser


Index: gc_lang/fr/webext/panel/main.js
==================================================================
--- gc_lang/fr/webext/panel/main.js
+++ gc_lang/fr/webext/panel/main.js
@@ -96,10 +96,17 @@
                 browser.runtime.sendMessage({
                     sCommand: "openLexiconEditor",
                     dParam: { "dictionary": "__personal__"},
                     dInfo: {}
                 });
+            }
+            else if (xElem.id == "restart_worker") {
+                browser.runtime.sendMessage({
+                    sCommand: "restartWorker",
+                    dParam: { "nDelayLimit": 3 },
+                    dInfo: {}
+                });
             }
         } else if (xElem.className.startsWith("select")) {
             showPage(xElem.dataset.page);
         }/* else if (xElem.tagName === "A") {
             openURL(xElem.getAttribute("href"));