Index: gc_lang/fr/webext/background.js
==================================================================
--- gc_lang/fr/webext/background.js
+++ gc_lang/fr/webext/background.js
@@ -12,27 +12,19 @@
 let xGCEWorker = new Worker("gce_worker.js");
 
 xGCEWorker.onmessage = function (e) {
     // https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent
     try {
-        let {sActionDone, result, dInfo, bError} = e.data;
+        let {sActionDone, result, dInfo} = e.data;
         switch (sActionDone) {
             case "init":
                 console.log("INIT DONE");
                 break;
             case "parse":
-                console.log("GRAMMAR ERRORS");
-                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);
-                }
-                break;
             case "parseAndSpellcheck":
-                console.log("SPELLING AND GRAMMAR ERRORS");
+            case "getListOfTokens":
+                console.log("Action done: " + sActionDone);
                 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");
@@ -50,25 +42,10 @@
             case "getOptions":
             case "getDefaultOptions":
             case "setOptions":
             case "setOption":
                 console.log("OPTIONS");
-                
-                break;
-            case "getListOfTokens":
-                console.log("TOKENS");
-                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;
             default:
                 console.log("Unknown command: " + sActionDone);
                 console.log(result);
         }
@@ -128,11 +105,11 @@
                 xPort.postMessage({sActionDone: "getCurrentTabId", result: "getCurrentTabId()", dInfo: null, bError: false});
                 break;
             case "parse":
             case "parseAndSpellcheck":
             case "getListOfTokens":
-                oRequest.dInfo.iReturnPort = iPortId; // we pass the id of the return port to received answer
+                oRequest.dInfo.iReturnPort = iPortId; // we pass the id of the return port to receive answer
                 console.log(oRequest);
                 xGCEWorker.postMessage(oRequest);
                 break;
             default:
                 console.log("[background] Unknown command: " + oRequest.sCommand);

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
@@ -96,46 +96,44 @@
 .grammalecte_close_button:hover {
     background-color: hsl(0, 100%, 60%);
 }
 
 .grammalecte_panel_content {
-    height: calc(100% - 45px); /* panel height - title_bar */
+    height: calc(100% - 60px); /* panel height - title_bar */
     overflow: auto;
 }
 
 
 /*
     Lexicographer
 */
 #grammalecte_lxg_panel_content {
-    padding: 10px;
+    padding: 5px;
+    font-size: 13px;
 }
 
 .grammalecte_lxg_list_of_tokens {
-    margin: 10px 5px;
+    margin: 10px 0;
     padding: 10px;
-    background-color: hsla(0, 0%, 90%, 1);
+    background-color: hsla(0, 0%, 96%, 1);
     border-radius: 2px;
 }
 
-.grammalecte_token div {
-    margin: 8px;
+.grammalecte_token  {
+    padding: 4px 0;
 }
-.grammalecte_token div.separator {
+.grammalecte_token .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;
+    margin: 0 0 5px 5px;
 }
 .grammalecte_token b {
     background-color: hsla(150, 10%, 50%, 1);
     color: hsla(0, 0%, 96%, 1);
     padding: 2px 5px;

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
@@ -27,12 +27,16 @@
     },
 
     addListOfTokens: function (lTokens) {
         try {
             let xNodeDiv = createNode("div", {className: "grammalecte_lxg_list_of_tokens"});
-            for (let oToken of lTokens) {
-                xNodeDiv.appendChild(this._createTokenNode(oToken));
+            if (lTokens.length > 0) {
+                for (let oToken of lTokens) {
+                    xNodeDiv.appendChild(this._createTokenNode(oToken));
+                }
+            } else {
+                xNodeDiv.appendChild(document.createTextNode("Aucun token connu détecté.")); 
             }
             this._xContentNode.appendChild(xNodeDiv);
         }
         catch (e) {
             showError(e);

Index: gc_lang/fr/webext/gce_worker.js
==================================================================
--- gc_lang/fr/webext/gce_worker.js
+++ gc_lang/fr/webext/gce_worker.js
@@ -52,15 +52,16 @@
     for we need the path of the extension to load data stored in JSON files.
     This path is retrieved in background.js and passed with the event “init”.
 */
 
 
-function createResponse (sActionDone, result, dInfo, bError=false) {
+function createResponse (sActionDone, result, dInfo, bEnd, bError=false) {
     return {
         "sActionDone": sActionDone,
         "result": result, // can be of any type
         "dInfo": dInfo,
+        "bEnd": bEnd,
         "bError": bError
     };
 }
 
 function createErrorResult (e, sDescr="no description") {
@@ -156,15 +157,15 @@
             bInitDone = true;
         } else {
             console.log("[Worker] Already initialized…")
         }
         // we always retrieve options from the gc_engine, for setOptions filters obsolete options
-        postMessage(createResponse("init", gc_engine.getOptions().gl_toString(), dInfo));
+        postMessage(createResponse("init", gc_engine.getOptions().gl_toString(), dInfo, true));
     }
     catch (e) {
         helpers.logerror(e);
-        postMessage(createResponse("init", createErrorResult(e, "init failed"), dInfo, true));
+        postMessage(createResponse("init", createErrorResult(e, "init failed"), dInfo, true, true));
     }
 }
 
 
 function parse (sText, sCountry, bDebug, bContext, dInfo={}) {
@@ -173,34 +174,34 @@
 }
 
 function parseAndSpellcheck (sText, sCountry, bDebug, bContext, dInfo={}) {
     let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
     let aSpellErr = oTokenizer.getSpellingErrors(sText, oDict);
-    postMessage(createResponse("parseAndSpellcheck", {aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo));
+    postMessage(createResponse("parseAndSpellcheck", {aGrammErr: aGrammErr, aSpellErr: aSpellErr}, dInfo, true));
 }
 
 function getOptions (dInfo={}) {
-    postMessage(createResponse("getOptions", gc_engine.getOptions().gl_toString(), dInfo));
+    postMessage(createResponse("getOptions", gc_engine.getOptions().gl_toString(), dInfo, true));
 }
 
 function getDefaultOptions (dInfo={}) {
-    postMessage(createResponse("getDefaultOptions", gc_engine.getDefaultOptions().gl_toString(), dInfo));
+    postMessage(createResponse("getDefaultOptions", gc_engine.getDefaultOptions().gl_toString(), dInfo, true));
 }
 
 function setOptions (sGCOptions, dInfo={}) {
     gc_engine.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
-    postMessage(createResponse("setOptions", gc_engine.getOptions().gl_toString(), dInfo));
+    postMessage(createResponse("setOptions", gc_engine.getOptions().gl_toString(), dInfo, true));
 }
 
 function setOption (sOptName, bValue, dInfo={}) {
     gc_engine.setOptions(new Map([ [sOptName, bValue] ]));
-    postMessage(createResponse("setOption", gc_engine.getOptions().gl_toString(), dInfo));
+    postMessage(createResponse("setOption", gc_engine.getOptions().gl_toString(), dInfo, true));
 }
 
 function resetOptions (dInfo={}) {
     gc_engine.resetOptions();
-    postMessage(createResponse("resetOptions", gc_engine.getOptions().gl_toString(), dInfo));
+    postMessage(createResponse("resetOptions", gc_engine.getOptions().gl_toString(), dInfo, true));
 }
 
 function tests () {
     console.log(conj.getConj("devenir", ":E", ":2s"));
     console.log(mfsp.getMasForm("emmerdeuse", true));
@@ -212,24 +213,24 @@
     }
 }
 
 function textToTest (sText, sCountry, bDebug, bContext, dInfo={}) {
     if (!gc_engine || !oDict) {
-        postMessage(createResponse("textToTest", "# Grammar checker or dictionary not loaded.", dInfo));
+        postMessage(createResponse("textToTest", "# Grammar checker or dictionary not loaded.", dInfo, true));
         return;
     }
     let aGrammErr = gc_engine.parse(sText, sCountry, bDebug, bContext);
     let sMsg = "";
     for (let oErr of aGrammErr) {
         sMsg += text.getReadableError(oErr) + "\n";
     }
-    postMessage(createResponse("textToTest", sMsg, dInfo));
+    postMessage(createResponse("textToTest", sMsg, dInfo, true));
 }
 
 function fullTests (sGCOptions="", dInfo={}) {
     if (!gc_engine || !oDict) {
-        postMessage(createResponse("fullTests", "# Grammar checker or dictionary not loaded.", dInfo));
+        postMessage(createResponse("fullTests", "# Grammar checker or dictionary not loaded.", dInfo, true));
         return;
     }
     let dMemoOptions = gc_engine.getOptions();
     if (sGCOptions) {
         gc_engine.setOptions(helpers.objectToMap(JSON.parse(sGCOptions)));
@@ -238,29 +239,32 @@
     for (let sRes of oTest.testParse()) {
         sMsg += sRes + "\n";
         console.log(sRes);
     }
     gc_engine.setOptions(dMemoOptions);
-    postMessage(createResponse("fullTests", sMsg, dInfo));
+    postMessage(createResponse("fullTests", sMsg, dInfo, true));
 }
 
 
 
 // Lexicographer
 
 function getListOfTokens (sText, dInfo={}) {
     try {
-        let aElem = [];
-        let aRes = null;
-        for (let oToken of oTokenizer.genTokens(sText)) {
-            aRes = oLxg.getInfoForToken(oToken);
-            if (aRes) {
-                aElem.push(aRes);
-            }
-        }
-        postMessage(createResponse("getListOfTokens", aElem, dInfo));
+        for (let sParagraph of text.getParagraph(sText)) {
+            let aElem = [];
+            let aRes = null;
+            for (let oToken of oTokenizer.genTokens(sParagraph)) {
+                aRes = oLxg.getInfoForToken(oToken);
+                if (aRes) {
+                    aElem.push(aRes);
+                }
+            }
+            postMessage(createResponse("getListOfTokens", aElem, dInfo, false));
+        }
+        postMessage(createResponse("getListOfTokens", null, dInfo, true));
     }
     catch (e) {
         helpers.logerror(e);
-        postMessage(createResponse("getListOfTokens", createErrorResult(e, "no tokens"), dInfo, true));
+        postMessage(createResponse("getListOfTokens", createErrorResult(e, "no tokens"), dInfo, true, true));
     }
 }