Index: gc_lang/fr/webext/background.js
==================================================================
--- gc_lang/fr/webext/background.js
+++ gc_lang/fr/webext/background.js
@@ -1,6 +1,10 @@
-// Background 
+// Background
+
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, oGrammalecte, helpers, showError, Worker, chrome, console */
 
 "use strict";
 
 
 function showError (e) {
@@ -250,10 +254,11 @@
                 console.log("[background] Unknown command: " + sCommand);
                 console.log(oRequest);
         }
     });
     //xPort.postMessage({sActionDone: "newId", result: iPortId});
+    xPort.postMessage({sActionDone: "init", sUrl: browser.extension.getURL("")});
 }
 
 browser.runtime.onConnect.addListener(handleConnexion);
 
 
@@ -327,11 +332,11 @@
             break;
         default:
             console.log("[Background] Unknown menu id: " + xInfo.menuItemId);
             console.log(xInfo);
             console.log(xTab);
-    }    
+    }
 });
 
 
 /*
     Keyboard shortcuts

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
@@ -1,7 +1,11 @@
 // Modify page
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, GrammalecteMenu, GrammalecteTextFormatter, GrammalecteLexicographer, GrammalecteGrammarChecker, GrammalecteMessageBox, showError, MutationObserver, chrome, document, console */
+
 /*
     JS sucks (again, and again, and again, and again…)
     Not possible to load content from within the extension:
     https://bugzilla.mozilla.org/show_bug.cgi?id=1267027
     No SharedWorker, no images allowed for now…
@@ -51,10 +55,12 @@
     oMessageBox: null,
 
     xRightClickedNode: null,
 
     xObserver: null,
+
+    sExtensionUrl: null,
 
     listenRightClick: function () {
         // Node where a right click is done
         // Bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1325814
         document.addEventListener('contextmenu', function (xEvent) {
@@ -131,34 +137,34 @@
         this.createMenus();
     },
 
     createTFPanel: function () {
         if (this.oTFPanel === null) {
-            this.oTFPanel = new GrammalecteTextFormatter("grammalecte_tf_panel", "Formateur de texte", 760, 600, false);
+            this.oTFPanel = new GrammalecteTextFormatter(this.sExtensionUrl, "grammalecte_tf_panel", "Formateur de texte", 760, 600, false);
             //this.oTFPanel.logInnerHTML();
             this.oTFPanel.insertIntoPage();
             this.oTFPanel.adjustHeight();
         }
     },
 
     createLxgPanel: function () {
         if (this.oLxgPanel === null) {
-            this.oLxgPanel = new GrammalecteLexicographer("grammalecte_lxg_panel", "Lexicographe", 500, 700);
+            this.oLxgPanel = new GrammalecteLexicographer(this.sExtensionUrl, "grammalecte_lxg_panel", "Lexicographe", 500, 700);
             this.oLxgPanel.insertIntoPage();
         }
     },
 
     createGCPanel: function () {
         if (this.oGCPanel === null) {
-            this.oGCPanel = new GrammalecteGrammarChecker("grammalecte_gc_panel", "Grammalecte", 500, 700);
+            this.oGCPanel = new GrammalecteGrammarChecker(this.sExtensionUrl, "grammalecte_gc_panel", "Grammalecte", 500, 700);
             this.oGCPanel.insertIntoPage();
         }
     },
 
     createMessageBox: function () {
         if (this.oMessageBox === null) {
-            this.oMessageBox = new GrammalecteMessageBox("grammalecte_message_box", "Grammalecte");
+            this.oMessageBox = new GrammalecteMessageBox(this.sExtensionUrl, "grammalecte_message_box", "Grammalecte");
             this.oMessageBox.insertIntoPage();
         }
     },
 
     startGCPanel: function (xNode=null) {
@@ -208,11 +214,11 @@
         }
         catch (e) {
             showError(e);
         }
     }
-}
+};
 
 
 /*
     Connexion to the background
 */
@@ -220,10 +226,13 @@
 
 xGrammalectePort.onMessage.addListener(function (oMessage) {
     let {sActionDone, result, dInfo, bEnd, bError} = oMessage;
     let sText = "";
     switch (sActionDone) {
+        case "init":
+            oGrammalecte.sExtensionUrl = oMessage.sUrl;
+            break;
         case "parseAndSpellcheck":
             if (!bEnd) {
                 oGrammalecte.oGCPanel.addParagraphResult(result);
             } else {
                 oGrammalecte.oGCPanel.stopWaitIcon();

Index: gc_lang/fr/webext/content_scripts/message_box.js
==================================================================
--- gc_lang/fr/webext/content_scripts/message_box.js
+++ gc_lang/fr/webext/content_scripts/message_box.js
@@ -1,15 +1,30 @@
 // JavaScript
 // Panel creator
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global oGrammalecte, xGrammalectePort, showError, window, document, console */
+
 "use strict";
 
 
 class GrammalecteMessageBox {
 
-    constructor (sId, sTitle) {
+    constructor (sUrl, sId, sTitle) {
         this.sId = sId;
+        this.sUrl = sUrl;
+
+        this.bShadow = document.body.createShadowRoot || document.body.attachShadow;
+        if (this.bShadow){
+            this.oShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"});
+            this.oShadow = this.oShadowPanel.attachShadow({mode: "open"});
+            this.oParent = this.oShadow;
+        } else {
+            this.oParent = document;
+        }
+
         this.xMessageBoxBar = oGrammalecte.createNode("div", {className: "grammalecte_message_box_bar"});
         this.xMessageBoxContent = oGrammalecte.createNode("div", {className: "grammalecte_message_box_content"});
         this.xMessageBox = this._createPanel(sTitle);
     }
 
@@ -48,11 +63,22 @@
         xButton.onclick = function () { this.hide(); }.bind(this);  // better than writing “let that = this;” before the function?
         return xButton;
     }
 
     insertIntoPage () {
-        document.body.appendChild(this.xMessageBox);
+        if (this.bShadow){
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/panel.css"})
+            );
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/message_box.css"})
+            );
+            this.oShadow.appendChild(this.xMessageBox);
+            document.body.appendChild(this.oShadowPanel);
+        } else {
+            document.body.appendChild(this.xMessageBox);
+        }
     }
 
     show () {
         this.xMessageBox.style.display = "block";
     }

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
@@ -1,18 +1,33 @@
 // JavaScript
 // Panel creator
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, oGrammalecte, xGrammalectePort, showError, window, document, console */
+
 "use strict";
 
 
 class GrammalectePanel {
 
-    constructor (sId, sTitle, nWidth, nHeight, bFlexible=true) {
+    constructor (sUrl, sId, sTitle, nWidth, nHeight, bFlexible=true) {
         this.sId = sId;
+        this.sUrl = sUrl;
         this.nWidth = nWidth;
         this.nHeight = nHeight;
         this.bFlexible = bFlexible;
+
+        this.bShadow = document.body.createShadowRoot || document.body.attachShadow;
+        if (this.bShadow){
+            this.oShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"});
+            this.oShadow = this.oShadowPanel.attachShadow({mode: "open"});
+            this.oParent = this.oShadow;
+        } else {
+            this.oParent = document;
+        }
+
         this.xPanelBar = oGrammalecte.createNode("div", {className: "grammalecte_panel_bar"});
         this.xPanelContent = oGrammalecte.createNode("div", {className: "grammalecte_panel_content"});
         this.xWaitIcon = this._createWaitIcon();
         this.xPanel = this._createPanel(sTitle);
         this.center();
@@ -81,11 +96,28 @@
         xButton.onclick = function () { this.hide(); }.bind(this);  // better than writing “let that = this;” before the function?
         return xButton;
     }
 
     insertIntoPage () {
-        document.body.appendChild(this.xPanel);
+        if (this.bShadow){
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/panel.css"})
+            );
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/panel_gc.css"})
+            );
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/panel_lxg.css"})
+            );
+            this.oShadow.appendChild(
+                oGrammalecte.createNode("link", {rel: "stylesheet", type: "text/css", media: "all", href: this.sUrl+"content_scripts/panel_tf.css"})
+            );
+            this.oShadow.appendChild(this.xPanel);
+            document.body.appendChild(this.oShadowPanel);
+        } else {
+            document.body.appendChild(this.xPanel);
+        }
     }
 
     show () {
         this.xPanel.style.display = "block";
     }
@@ -137,11 +169,11 @@
 
     logInnerHTML () {
         // for debugging
         console.log(this.xPanel.innerHTML);
     }
-    
+
     startWaitIcon () {
         this.xWaitIcon.style.visibility = "visible";
     }
 
     stopWaitIcon () {

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
@@ -1,7 +1,11 @@
 // JavaScript
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, oGrammalecte, xGrammalectePort, showError, window, document, console */
+
 "use strict";
 
 function onGrammalecteGCPanelClick (xEvent) {
     try {
         let xElem = xEvent.target;
@@ -48,11 +52,11 @@
         this.aIgnoredErrors = new Set();
         this.xContentNode = oGrammalecte.createNode("div", {id: "grammalecte_gc_panel_content"});
         this.xParagraphList = oGrammalecte.createNode("div", {id: "grammalecte_paragraph_list"});
         this.xContentNode.appendChild(this.xParagraphList);
         this.xPanelContent.addEventListener("click", onGrammalecteGCPanelClick, false);
-        this.oTooltip = new GrammalecteTooltip(this.xContentNode);
+        this.oTooltip = new GrammalecteTooltip(this.oParent, this.xContentNode);
         this.xPanelContent.appendChild(this.xContentNode);
         this.oNodeControl = new GrammalecteNodeControl();
     }
 
     start (xNode=null) {
@@ -106,11 +110,11 @@
         }
     }
 
     recheckParagraph (iParaNum) {
         let sParagraphId = "grammalecte_paragraph" + iParaNum;
-        let xParagraph = document.getElementById(sParagraphId);
+        let xParagraph = this.oParent.getElementById(sParagraphId);
         this.blockParagraph(xParagraph);
         let sText = this.purgeText(xParagraph.textContent);
         xGrammalectePort.postMessage({
             sCommand: "parseAndSpellcheck1",
             dParam: {sText: sText, sCountry: "FR", bDebug: false, bContext: false},
@@ -120,11 +124,11 @@
         this.oNodeControl.write();
     }
 
     refreshParagraph (sParagraphId, oResult) {
         try {
-            let xParagraph = document.getElementById(sParagraphId);
+            let xParagraph = this.oParent.getElementById(sParagraphId);
             xParagraph.className = (oResult.aGrammErr.length || oResult.aSpellErr.length) ? "grammalecte_paragraph softred" : "grammalecte_paragraph";
             xParagraph.textContent = "";
             this._tagParagraph(xParagraph, oResult.sParagraph, sParagraphId.slice(21), oResult.aGrammErr, oResult.aSpellErr);
             this.freeParagraph(xParagraph);
         }
@@ -193,28 +197,28 @@
         return xNodeErr;
     }
 
     blockParagraph (xParagraph) {
         xParagraph.contentEditable = "false";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Analyse…";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(0, 50%, 50%)";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "0 0 0 3px hsla(0, 100%, 50%, .2)";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Analyse…";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(0, 50%, 50%)";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "0 0 0 3px hsla(0, 100%, 50%, .2)";
     }
 
     freeParagraph (xParagraph) {
         xParagraph.contentEditable = "true";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Réanalyser";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(120, 30%, 50%)";
-        document.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "none";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Réanalyser";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(120, 30%, 50%)";
+        this.oParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.boxShadow = "none";
     }
 
     applySuggestion (sNodeSuggId) { // sugg
         try {
-            let sErrorId = document.getElementById(sNodeSuggId).dataset.error_id;
+            let sErrorId = this.oParent.getElementById(sNodeSuggId).dataset.error_id;
             //let sParaNum = sErrorId.slice(0, sErrorId.indexOf("-"));
-            let xNodeErr = document.getElementById("grammalecte_err" + sErrorId);
-            xNodeErr.textContent = document.getElementById(sNodeSuggId).textContent;
+            let xNodeErr = this.oParent.getElementById("grammalecte_err" + sErrorId);
+            xNodeErr.textContent = this.oParent.getElementById(sNodeSuggId).textContent;
             xNodeErr.className = "grammalecte_error_corrected";
             xNodeErr.removeAttribute("style");
             this.oTooltip.hide();
             this.recheckParagraph(parseInt(sErrorId.slice(0, sErrorId.indexOf("-"))));
         }
@@ -223,12 +227,12 @@
         }
     }
 
     ignoreError (sIgnoreButtonId) {  // ignore
         try {
-            let sErrorId = document.getElementById(sIgnoreButtonId).dataset.error_id;
-            let xNodeErr = document.getElementById("grammalecte_err" + sErrorId);
+            let sErrorId = this.oParent.getElementById(sIgnoreButtonId).dataset.error_id;
+            let xNodeErr = this.oParent.getElementById("grammalecte_err" + sErrorId);
             this.aIgnoredErrors.add(xNodeErr.dataset.ignored_key);
             xNodeErr.className = "grammalecte_error_ignored";
             this.oTooltip.hide();
         }
         catch (e) {
@@ -254,23 +258,23 @@
         function setClipboardData (xEvent) {
             document.removeEventListener("copy", setClipboardData, true);
             xEvent.stopImmediatePropagation();
             xEvent.preventDefault();
             xEvent.clipboardData.setData("text/plain", sText);
-        };
+        }
 
         document.addEventListener("copy", setClipboardData, true);
         document.execCommand("copy");
     }
 
     copyTextToClipboard () {
         this.startWaitIcon();
         try {
-            let xClipboardButton = document.getElementById("grammalecte_clipboard_button");
+            let xClipboardButton = this.oParent.getElementById("grammalecte_clipboard_button");
             xClipboardButton.textContent = "->>";
             let sText = "";
-            for (let xNode of document.getElementsByClassName("grammalecte_paragraph")) {
+            for (let xNode of this.oParent.getElementsByClassName("grammalecte_paragraph")) {
                 sText += xNode.textContent + "\n";
             }
             this._copyToClipboard(sText);
             xClipboardButton.textContent = "OK";
             window.setTimeout(function() { xClipboardButton.textContent = "∑"; } , 2000);
@@ -283,11 +287,12 @@
 }
 
 
 class GrammalecteTooltip {
 
-    constructor (xContentNode) {
+    constructor (oParent, xContentNode) {
+        this.oParent = oParent;
         this.sErrorId = null;
         this.bDebug = false;
         this.xTooltip = oGrammalecte.createNode("div", {id: "grammalecte_tooltip"});
         this.xTooltipArrow = oGrammalecte.createNode("img", {
             id: "grammalecte_tooltip_arrow",
@@ -314,11 +319,11 @@
         xContentNode.appendChild(this.xTooltipArrow);
     }
 
     show (sNodeErrorId) {  // err
         try {
-            let xNodeErr = document.getElementById(sNodeErrorId);
+            let xNodeErr = this.oParent.getElementById(sNodeErrorId);
             this.sErrorId = xNodeErr.dataset.error_id; // we store error_id here to know if spell_suggestions are given to the right word.
             let nTooltipLeftLimit = oGrammalecte.oGCPanel.getWidth() - 330; // paragraph width - tooltip width
             let nArrowLimit = oGrammalecte.oGCPanel.getWidth() - 20;
             this.xTooltipArrow.style.top = (xNodeErr.offsetTop + 16) + "px";
             let nUsefulErrorWidth = ((xNodeErr.offsetLeft + xNodeErr.offsetWidth) > nArrowLimit) ? (nArrowLimit - xNodeErr.offsetLeft) : xNodeErr.offsetWidth;
@@ -325,31 +330,31 @@
             this.xTooltipArrow.style.left = (xNodeErr.offsetLeft + Math.floor((nUsefulErrorWidth / 2)) - 4) + "px"; // 4 is half the width of the arrow.
             this.xTooltip.style.top = (xNodeErr.offsetTop + 20) + "px";
             this.xTooltip.style.left = (xNodeErr.offsetLeft > nTooltipLeftLimit) ? nTooltipLeftLimit + "px" : xNodeErr.offsetLeft + "px";
             if (xNodeErr.dataset.error_type === "grammar") {
                 // grammar error
-                document.getElementById("grammalecte_tooltip_db_search").style.display = "none";
+                this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "none";
                 if (xNodeErr.dataset.gc_message.includes(" ##")) {
                     this.bDebug = true;
                     // display rule id
                     let n = xNodeErr.dataset.gc_message.indexOf(" ##");
-                    document.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message.slice(0, n);
-                    document.getElementById("grammalecte_tooltip_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2);
-                    document.getElementById("grammalecte_tooltip_rule_id").style.display = "block";
+                    this.oParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message.slice(0, n);
+                    this.oParent.getElementById("grammalecte_tooltip_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2);
+                    this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "block";
                 } else {
                     this.bDebug = false;
-                    document.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message;
-                    document.getElementById("grammalecte_tooltip_rule_id").style.display = "none";
+                    this.oParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message;
+                    this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "none";
                 }
                 if (xNodeErr.dataset.gc_url != "") {
-                    document.getElementById("grammalecte_tooltip_url").dataset.url = xNodeErr.dataset.gc_url;
-                    document.getElementById("grammalecte_tooltip_url").style.display = "inline";
+                    this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = xNodeErr.dataset.gc_url;
+                    this.oParent.getElementById("grammalecte_tooltip_url").style.display = "inline";
                 } else {
-                    document.getElementById("grammalecte_tooltip_url").dataset.url = "";
-                    document.getElementById("grammalecte_tooltip_url").style.display = "none";
+                    this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = "";
+                    this.oParent.getElementById("grammalecte_tooltip_url").style.display = "none";
                 }
-                document.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id;
+                this.oParent.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id;
                 let iSugg = 0;
                 this.clearSuggestionBlock();
                 if (xNodeErr.dataset.suggestions.length > 0) {
                     for (let sSugg of xNodeErr.dataset.suggestions.split("|")) {
                         this.xTooltipSuggBlock.appendChild(this._createSuggestion(xNodeErr.dataset.error_id, 0, iSugg, sSugg));
@@ -360,20 +365,20 @@
                     this.xTooltipSuggBlock.textContent = "Aucune.";
                 }
             }
             if (xNodeErr.dataset.error_type === "spelling") {
                 // spelling mistake
-                document.getElementById("grammalecte_tooltip_message").textContent = "Mot inconnu du dictionnaire.";
-                document.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id;
-                document.getElementById("grammalecte_tooltip_rule_id").style.display = "none";
-                document.getElementById("grammalecte_tooltip_url").dataset.url = "";
-                document.getElementById("grammalecte_tooltip_url").style.display = "none";
+                this.oParent.getElementById("grammalecte_tooltip_message").textContent = "Mot inconnu du dictionnaire.";
+                this.oParent.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id;
+                this.oParent.getElementById("grammalecte_tooltip_rule_id").style.display = "none";
+                this.oParent.getElementById("grammalecte_tooltip_url").dataset.url = "";
+                this.oParent.getElementById("grammalecte_tooltip_url").style.display = "none";
                 if (this.bDebug) {
-                    document.getElementById("grammalecte_tooltip_db_search").style.display = "inline";
-                    document.getElementById("grammalecte_tooltip_db_search").dataset.url = "https://www.dicollecte.org/dictionary.php?prj=fr&lemma="+xNodeErr.textContent;
+                    this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "inline";
+                    this.oParent.getElementById("grammalecte_tooltip_db_search").dataset.url = "https://www.dicollecte.org/dictionary.php?prj=fr&lemma="+xNodeErr.textContent;
                 } else {
-                    document.getElementById("grammalecte_tooltip_db_search").style.display = "none";
+                    this.oParent.getElementById("grammalecte_tooltip_db_search").style.display = "none";
                 }
                 this.clearSuggestionBlock();
                 this.xTooltipSuggBlock.textContent = "Recherche de graphies possibles…";
                 xGrammalectePort.postMessage({
                     sCommand: "getSpellSuggestions",
@@ -415,11 +420,11 @@
 
     setSpellSuggestionsFor (sWord, aSugg, iSuggBlock, sErrorId) {
         // spell checking suggestions
         try {
             if (sErrorId === this.sErrorId) {
-                let xSuggBlock = document.getElementById("grammalecte_tooltip_sugg_block");
+                let xSuggBlock = this.oParent.getElementById("grammalecte_tooltip_sugg_block");
                 if (iSuggBlock == 0) {
                     xSuggBlock.textContent = "";
                 }
                 if (!aSugg || aSugg.length == 0) {
                     if (iSuggBlock == 0) {
@@ -437,11 +442,11 @@
                     }
                 }
             }
         }
         catch (e) {
-            let xSuggBlock = document.getElementById("grammalecte_tooltip_sugg_block");
+            let xSuggBlock = this.oParent.getElementById("grammalecte_tooltip_sugg_block");
             xSuggBlock.appendChild(document.createTextNode("# Oups. Le mécanisme de suggestion orthographique a rencontré un bug… (Ce module est encore en phase β.)"));
             showError(e);
         }
     }
 }

Index: gc_lang/fr/webext/content_scripts/panel_lxg.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_lxg.js
+++ gc_lang/fr/webext/content_scripts/panel_lxg.js
@@ -1,7 +1,11 @@
 // JavaScript
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, oGrammalecte, showError, console */
+
 "use strict";
 
 
 class GrammalecteLexicographer extends GrammalectePanel {
 
@@ -83,10 +87,11 @@
             showError(e);
         }
     }
 
     setHidden (sClass, bHidden) {
-        for (let xNode of document.getElementsByClassName(sClass)) {
+        let elmOpt = this.oParent.getElementById('grammalecte_panel_content');
+        for (let xNode of elmOpt.getElementsByClassName(sClass)) {
             xNode.hidden = bHidden;
         }
     }
 }

Index: gc_lang/fr/webext/content_scripts/panel_tf.js
==================================================================
--- gc_lang/fr/webext/content_scripts/panel_tf.js
+++ gc_lang/fr/webext/content_scripts/panel_tf.js
@@ -1,8 +1,12 @@
 // JavaScript
 // Text formatter
 
+/* jshint esversion:6, -W097 */
+/* jslint esversion:6 */
+/* global GrammalectePanel, oGrammalecte, TextFormatter, bChrome, browser, showError, document, console */
+
 "use strict";
 
 
 class GrammalecteTextFormatter extends GrammalectePanel {
 
@@ -180,20 +184,20 @@
             }
         }
     }
 
     switchGroup (sOptName) {
-        if (document.getElementById(sOptName).dataset.selected == "true") {
-            document.getElementById(sOptName.slice(2)).style.opacity = 1;
+        if (this.oParent.getElementById(sOptName).dataset.selected == "true") {
+            this.oParent.getElementById(sOptName.slice(2)).style.opacity = 1;
         } else {
-            document.getElementById(sOptName.slice(2)).style.opacity = 0.3;
+            this.oParent.getElementById(sOptName.slice(2)).style.opacity = 0.3;
         }
         this.resetProgressBar();
     }
 
     switchOption (sOptName) {
-        let xOption = document.getElementById(sOptName);
+        let xOption = this.oParent.getElementById(sOptName);
         if (xOption.dataset.linked_ids === "") {
             xOption.dataset.selected = (xOption.dataset.selected == "true") ? "false" : "true";
             xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off");
         } else {
             this.setOption(sOptName, true);
@@ -202,60 +206,64 @@
             }
         }
     }
 
     setOption (sOptName, bValue) {
-        let xOption = document.getElementById(sOptName);
+        let xOption = this.oParent.getElementById(sOptName);
         xOption.dataset.selected = bValue;
         xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off");
     }
 
     reset () {
         this.resetProgressBar();
-        for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) {
+        //on Shadow DOM getElementsByClassName don't work directly ;)
+        let elmOpt = this.oParent.getElementById('grammalecte_tf_options');
+        for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) {
             xOption.dataset.selected = xOption.dataset.default;
             xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off");
             if (xOption.id.startsWith("o_group_")) {
                 this.switchGroup(xOption.id);
             }
         }
     }
 
     resetProgressBar () {
-        document.getElementById('grammalecte_tf_progressbar').value = 0;
-        document.getElementById('grammalecte_tf_time_res').textContent = "";
+        this.oParent.getElementById('grammalecte_tf_progressbar').value = 0;
+        this.oParent.getElementById('grammalecte_tf_time_res').textContent = "";
     }
 
     setOptions (oOptions) {
         if (oOptions.hasOwnProperty("tf_options")) {
             oOptions = oOptions.tf_options;
         }
-        for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) {
+        let elmOpt = this.oParent.getElementById('grammalecte_tf_options');
+        for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) {
             //console.log(xOption.id + " > " + oOptions.hasOwnProperty(xOption.id) + ": " + oOptions[xOption.id] + " [" + xOption.dataset.default + "]");
             xOption.dataset.selected = (oOptions.hasOwnProperty(xOption.id)) ? oOptions[xOption.id] : xOption.dataset.default;
             xOption.className = (xOption.dataset.selected == "true") ? xOption.className.replace("_off", "_on") : xOption.className.replace("_on", "_off");
-            if (document.getElementById("res_"+xOption.id) !== null) {
-                document.getElementById("res_"+xOption.id).textContent = "";
+            if (this.oParent.getElementById("res_"+xOption.id) !== null) {
+                this.oParent.getElementById("res_"+xOption.id).textContent = "";
             }
             if (xOption.id.startsWith("o_group_")) {
                 this.switchGroup(xOption.id);
             }
         }
     }
 
     saveOptions () {
         let oOptions = {};
-        for (let xOption of document.getElementsByClassName("grammalecte_tf_option")) {
+        let elmOpt = this.oParent.getElementById('grammalecte_tf_options');
+        for (let xOption of elmOpt.getElementsByClassName("grammalecte_tf_option")) {
             oOptions[xOption.id] = (xOption.dataset.selected == "true");
             //console.log(xOption.id + ": " + xOption.checked);
         }
         browser.storage.local.set({"tf_options": oOptions});
     }
 
     isSelected (sOptName) {
-        if (document.getElementById(sOptName)) {
-            return (document.getElementById(sOptName).dataset.selected === "true");
+        if (this.oParent.getElementById(sOptName)) {
+            return (this.oParent.getElementById(sOptName).dataset.selected === "true");
         }
         return false;
     }
 
     apply () {
@@ -262,161 +270,161 @@
         try {
             const t0 = Date.now();
             //window.setCursor("wait"); // change pointer
             this.resetProgressBar();
             let sText = this.xTextArea.value.normalize("NFC");
-            document.getElementById('grammalecte_tf_progressbar').max = 7;
+            this.oParent.getElementById('grammalecte_tf_progressbar').max = 7;
             let n1 = 0, n2 = 0, n3 = 0, n4 = 0, n5 = 0, n6 = 0, n7 = 0;
 
             // Restructuration
             if (this.isSelected("o_group_struct")) {
                 if (this.isSelected("o_remove_hyphens_at_end_of_paragraphs")) {
                     [sText, n1] = this.removeHyphenAtEndOfParagraphs(sText);
-                    document.getElementById('res_o_remove_hyphens_at_end_of_paragraphs').textContent = n1;
+                    this.oParent.getElementById('res_o_remove_hyphens_at_end_of_paragraphs').textContent = n1;
                 }
                 if (this.isSelected("o_merge_contiguous_paragraphs")) {
                     [sText, n1] = this.mergeContiguousParagraphs(sText);
-                    document.getElementById('res_o_merge_contiguous_paragraphs').textContent = n1;
+                    this.oParent.getElementById('res_o_merge_contiguous_paragraphs').textContent = n1;
                 }
                 this.setOption("o_group_struct", false);
                 this.switchGroup("o_group_struct");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 1;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 1;
 
             // espaces surnuméraires
             if (this.isSelected("o_group_ssp")) {
                 if (this.isSelected("o_end_of_paragraph")) {
                     [sText, n1] = this.formatText(sText, "end_of_paragraph");
-                    document.getElementById('res_o_end_of_paragraph').textContent = n1;
+                    this.oParent.getElementById('res_o_end_of_paragraph').textContent = n1;
                 }
                 if (this.isSelected("o_between_words")) {
                     [sText, n1] = this.formatText(sText, "between_words");
-                    document.getElementById('res_o_between_words').textContent = n1;
+                    this.oParent.getElementById('res_o_between_words').textContent = n1;
                 }
                 if (this.isSelected("o_start_of_paragraph")) {
                     [sText, n1] = this.formatText(sText, "start_of_paragraph");
-                    document.getElementById('res_o_start_of_paragraph').textContent = n1;
+                    this.oParent.getElementById('res_o_start_of_paragraph').textContent = n1;
                 }
                 if (this.isSelected("o_before_punctuation")) {
                     [sText, n1] = this.formatText(sText, "before_punctuation");
-                    document.getElementById('res_o_before_punctuation').textContent = n1;
+                    this.oParent.getElementById('res_o_before_punctuation').textContent = n1;
                 }
                 if (this.isSelected("o_within_parenthesis")) {
                     [sText, n1] = this.formatText(sText, "within_parenthesis");
-                    document.getElementById('res_o_within_parenthesis').textContent = n1;
+                    this.oParent.getElementById('res_o_within_parenthesis').textContent = n1;
                 }
                 if (this.isSelected("o_within_square_brackets")) {
                     [sText, n1] = this.formatText(sText, "within_square_brackets");
-                    document.getElementById('res_o_within_square_brackets').textContent = n1;
+                    this.oParent.getElementById('res_o_within_square_brackets').textContent = n1;
                 }
                 if (this.isSelected("o_within_quotation_marks")) {
                     [sText, n1] = this.formatText(sText, "within_quotation_marks");
-                    document.getElementById('res_o_within_quotation_marks').textContent = n1;
+                    this.oParent.getElementById('res_o_within_quotation_marks').textContent = n1;
                 }
                 this.setOption("o_group_ssp", false);
                 this.switchGroup("o_group_ssp");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 2;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 2;
 
             // espaces insécables
             if (this.isSelected("o_group_nbsp")) {
                 if (this.isSelected("o_nbsp_before_punctuation")) {
                     [sText, n1] = this.formatText(sText, "nbsp_before_punctuation");
                     [sText, n2] = this.formatText(sText, "nbsp_repair");
-                    document.getElementById('res_o_nbsp_before_punctuation').textContent = n1 - n2;
+                    this.oParent.getElementById('res_o_nbsp_before_punctuation').textContent = n1 - n2;
                 }
                 if (this.isSelected("o_nbsp_within_quotation_marks")) {
                     [sText, n1] = this.formatText(sText, "nbsp_within_quotation_marks");
-                    document.getElementById('res_o_nbsp_within_quotation_marks').textContent = n1;
+                    this.oParent.getElementById('res_o_nbsp_within_quotation_marks').textContent = n1;
                 }
                 if (this.isSelected("o_nbsp_before_symbol")) {
                     [sText, n1] = this.formatText(sText, "nbsp_before_symbol");
-                    document.getElementById('res_o_nbsp_before_symbol').textContent = n1;
+                    this.oParent.getElementById('res_o_nbsp_before_symbol').textContent = n1;
                 }
                 if (this.isSelected("o_nbsp_within_numbers")) {
                     [sText, n1] = this.formatText(sText, "nbsp_within_numbers");
-                    document.getElementById('res_o_nbsp_within_numbers').textContent = n1;
+                    this.oParent.getElementById('res_o_nbsp_within_numbers').textContent = n1;
                 }
                 if (this.isSelected("o_nbsp_before_units")) {
                     [sText, n1] = this.formatText(sText, "nbsp_before_units");
-                    document.getElementById('res_o_nbsp_before_units').textContent = n1;
+                    this.oParent.getElementById('res_o_nbsp_before_units').textContent = n1;
                 }
                 if (this.isSelected("o_nbsp_titles")) {
                     [sText, n1] = this.formatText(sText, "nbsp_titles");
-                    document.getElementById('res_o_nbsp_titles').textContent = n1;
+                    this.oParent.getElementById('res_o_nbsp_titles').textContent = n1;
                 }
                 this.setOption("o_group_nbsp", false);
                 this.switchGroup("o_group_nbsp");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 3;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 3;
 
             // espaces manquants
             if (this.isSelected("o_group_typo")) {
                 if (this.isSelected("o_ts_units")) {
                     [sText, n1] = this.formatText(sText, "ts_units");
-                    document.getElementById('res_o_ts_units').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_units').textContent = n1;
                 }
             }
             if (this.isSelected("o_group_space")) {
                 if (this.isSelected("o_add_space_after_punctuation")) {
                     [sText, n1] = this.formatText(sText, "add_space_after_punctuation");
                     [sText, n2] = this.formatText(sText, "add_space_repair");
-                    document.getElementById('res_o_add_space_after_punctuation').textContent = n1 - n2;
+                    this.oParent.getElementById('res_o_add_space_after_punctuation').textContent = n1 - n2;
                 }
                 if (this.isSelected("o_add_space_around_hyphens")) {
                     [sText, n1] = this.formatText(sText, "add_space_around_hyphens");
-                    document.getElementById('res_o_add_space_around_hyphens').textContent = n1;
+                    this.oParent.getElementById('res_o_add_space_around_hyphens').textContent = n1;
                 }
                 this.setOption("o_group_space", false);
                 this.switchGroup("o_group_space");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 4;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 4;
 
             // suppression
             if (this.isSelected("o_group_delete")) {
                 if (this.isSelected("o_erase_non_breaking_hyphens")) {
                     [sText, n1] = this.formatText(sText, "erase_non_breaking_hyphens");
-                    document.getElementById('res_o_erase_non_breaking_hyphens').textContent = n1;
+                    this.oParent.getElementById('res_o_erase_non_breaking_hyphens').textContent = n1;
                 }
                 this.setOption("o_group_delete", false);
                 this.switchGroup("o_group_delete");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 5;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 5;
 
             // signes typographiques
             if (this.isSelected("o_group_typo")) {
                 if (this.isSelected("o_ts_apostrophe")) {
                     [sText, n1] = this.formatText(sText, "ts_apostrophe");
-                    document.getElementById('res_o_ts_apostrophe').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_apostrophe').textContent = n1;
                 }
                 if (this.isSelected("o_ts_ellipsis")) {
                     [sText, n1] = this.formatText(sText, "ts_ellipsis");
-                    document.getElementById('res_o_ts_ellipsis').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_ellipsis').textContent = n1;
                 }
                 if (this.isSelected("o_ts_dash_start")) {
                     if (this.isSelected("o_ts_m_dash_start")) {
                         [sText, n1] = this.formatText(sText, "ts_m_dash_start");
                     } else {
                         [sText, n1] = this.formatText(sText, "ts_n_dash_start");
                     }
-                    document.getElementById('res_o_ts_dash_start').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_dash_start').textContent = n1;
                 }
                 if (this.isSelected("o_ts_dash_middle")) {
                     if (this.isSelected("o_ts_m_dash_middle")) {
                         [sText, n1] = this.formatText(sText, "ts_m_dash_middle");
                     } else {
                         [sText, n1] = this.formatText(sText, "ts_n_dash_middle");
                     }
-                    document.getElementById('res_o_ts_dash_middle').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_dash_middle').textContent = n1;
                 }
                 if (this.isSelected("o_ts_quotation_marks")) {
                     [sText, n1] = this.formatText(sText, "ts_quotation_marks");
-                    document.getElementById('res_o_ts_quotation_marks').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_quotation_marks').textContent = n1;
                 }
                 if (this.isSelected("o_ts_spell")) {
                     [sText, n1] = this.formatText(sText, "ts_spell");
-                    document.getElementById('res_o_ts_spell').textContent = n1;
+                    this.oParent.getElementById('res_o_ts_spell').textContent = n1;
                 }
                 if (this.isSelected("o_ts_ligature")) {
                     // ligatures typographiques : fi, fl, ff, ffi, ffl, ft, st
                     if (this.isSelected("o_ts_ligature_do")) {
                         if (this.isSelected("o_ts_ligature_ffi")) {
@@ -462,55 +470,55 @@
                         }
                         if (this.isSelected("o_ts_ligature_st")) {
                             [sText, n7] = this.formatText(sText, "ts_ligature_st_undo");
                         }
                     }
-                    document.getElementById('res_o_ts_ligature').textContent = n1 + n2 + n3 + n4 + n5 + n6 + n7;
+                    this.oParent.getElementById('res_o_ts_ligature').textContent = n1 + n2 + n3 + n4 + n5 + n6 + n7;
                 }
                 this.setOption("o_group_typo", false);
                 this.switchGroup("o_group_typo");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = 6;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = 6;
 
             // divers
             if (this.isSelected("o_group_misc")) {
                 if (this.isSelected("o_ordinals_no_exponant")) {
                     if (this.isSelected("o_ordinals_exponant")) {
                         [sText, n1] = this.formatText(sText, "ordinals_exponant");
                     } else {
                         [sText, n1] = this.formatText(sText, "ordinals_no_exponant");
                     }
-                    document.getElementById('res_o_ordinals_no_exponant').textContent = n1;
+                    this.oParent.getElementById('res_o_ordinals_no_exponant').textContent = n1;
                 }
                 if (this.isSelected("o_etc")) {
                     [sText, n1] = this.formatText(sText, "etc");
-                    document.getElementById('res_o_etc').textContent = n1;
+                    this.oParent.getElementById('res_o_etc').textContent = n1;
                 }
                 if (this.isSelected("o_missing_hyphens")) {
                     [sText, n1] = this.formatText(sText, "missing_hyphens");
-                    document.getElementById('res_o_missing_hyphens').textContent = n1;
+                    this.oParent.getElementById('res_o_missing_hyphens').textContent = n1;
                 }
                 if (this.isSelected("o_ma_word")) {
                     [sText, n1] = this.formatText(sText, "ma_word");
                     if (this.isSelected("o_ma_1letter_lowercase")) {
                         [sText, n1] = this.formatText(sText, "ma_1letter_lowercase");
                         if (this.isSelected("o_ma_1letter_uppercase")) {
                             [sText, n1] = this.formatText(sText, "ma_1letter_uppercase");
                         }
                     }
-                    document.getElementById('res_o_ma_word').textContent = n1;
+                    this.oParent.getElementById('res_o_ma_word').textContent = n1;
                 }
                 this.setOption("o_group_misc", false);
                 this.switchGroup("o_group_misc");
             }
-            document.getElementById('grammalecte_tf_progressbar').value = document.getElementById('grammalecte_tf_progressbar').max;
+            this.oParent.getElementById('grammalecte_tf_progressbar').value = this.oParent.getElementById('grammalecte_tf_progressbar').max;
             // end of processing
 
             //window.setCursor("auto"); // restore pointer
 
             const t1 = Date.now();
-            document.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000);
+            this.oParent.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000);
             this.xTextArea.value = sText;
         }
         catch (e) {
             showError(e);
         }