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,14 +137,16 @@ 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("grammalecte_tf_panel", "Formateur de texte", 760, 615, false); //this.oTFPanel.logInnerHTML(); this.oTFPanel.insertIntoPage(); - this.oTFPanel.adjustHeight(); + window.setTimeout(function(self){ + self.oTFPanel.adjustHeight(); + }, 50, this); } }, createLxgPanel: function () { if (this.oLxgPanel === null) { @@ -207,12 +215,34 @@ return xNode; } catch (e) { showError(e); } + }, + + createStyle: function (sLinkCss, sLinkId=null, xNodeToAppendTo=null) { + try { + let xNode = document.createElement("link"); + Object.assign(xNode, { + rel: "stylesheet", + type: "text/css", + media: "all", + href: this.sExtensionUrl + sLinkCss + }); + if (sLinkId) { + Object.assign(xNode, {id: sLinkId}); + } + if (xNodeToAppendTo) { + xNodeToAppendTo.appendChild(xNode); + } + return xNode; + } + catch (e) { + showError(e); + } } -} +}; /* Connexion to the background */ @@ -220,10 +250,17 @@ xGrammalectePort.onMessage.addListener(function (oMessage) { let {sActionDone, result, dInfo, bEnd, bError} = oMessage; let sText = ""; switch (sActionDone) { + case "init": + oGrammalecte.sExtensionUrl = oMessage.sUrl; + // Start + oGrammalecte.listenRightClick(); + oGrammalecte.createMenus(); + oGrammalecte.observePage(); + break; case "parseAndSpellcheck": if (!bEnd) { oGrammalecte.oGCPanel.addParagraphResult(result); } else { oGrammalecte.oGCPanel.stopWaitIcon(); @@ -316,13 +353,5 @@ break; default: console.log("[Content script] Unknown command: " + sActionDone); } }); - - -/* - Start -*/ -oGrammalecte.listenRightClick(); -oGrammalecte.createMenus(); -oGrammalecte.observePage(); Index: gc_lang/fr/webext/content_scripts/menu.css ================================================================== --- gc_lang/fr/webext/content_scripts/menu.css +++ gc_lang/fr/webext/content_scripts/menu.css @@ -58,10 +58,11 @@ box-shadow: 0px 0px 2px hsla(210, 10%, 10%, .5); background-color: hsl(210, 50%, 30%); font-family: "Trebuchet MS", "Fira Sans", "Liberation Sans", sans-serif; z-index: 2147483640; /* maximum is 2147483647: https://stackoverflow.com/questions/491052/minimum-and-maximum-value-of-z-index */ text-align: left; + width: 220px; } @media print { .grammalecte_menu { display: none; } } Index: gc_lang/fr/webext/content_scripts/menu.js ================================================================== --- gc_lang/fr/webext/content_scripts/menu.js +++ gc_lang/fr/webext/content_scripts/menu.js @@ -1,7 +1,11 @@ // JavaScript +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global oGrammalecte, xGrammalectePort, showError, window, document */ + "use strict"; class GrammalecteMenu { @@ -12,19 +16,38 @@ this.xButton.onclick = () => { this.switchMenu(); }; this.xButton.style.zIndex = (xNode.style.zIndex.search(/^[0-9]+$/) !== -1) ? (parseInt(xNode.style.zIndex) + 1).toString() : xNode.style.zIndex; this.xMenu = this._createMenu(); let xStyle = window.getComputedStyle(this.xNode); - let nMarginTop = -1 * (8 + parseInt(xStyle.marginBottom.replace('px', ''), 10)); let xNodeInsertAfter = this.xNode; if (document.location.host == "twitter.com" && this.xNode.classList.contains('rich-editor')) { xNodeInsertAfter = this.xNode.parentNode; } - this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop); - this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8); + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; + if (this.bShadow) { + let nMarginTop = -1 * (parseInt(xStyle.marginBottom.replace('px', ''), 10)); + this.xShadowBtn = oGrammalecte.createNode("div", {style: "display:none;position:absolute;width:0;height:0;"}); + this.xShadowBtnNode = this.xShadowBtn.attachShadow({mode: "open"}); + oGrammalecte.createStyle("content_scripts/menu.css", null, this.xShadowBtnNode); + this.xShadowBtnNode.appendChild(this.xButton); + this._insertAfter(this.xShadowBtn, xNodeInsertAfter, nMarginTop); + + this.xShadowMenu = oGrammalecte.createNode("div", {id: this.sMenuId+"_shadow", style: "display:none;position:absolute;width:0;height:0;"}); + this.xShadowMenuNode = this.xShadowMenu.attachShadow({mode: "open"}); + oGrammalecte.createStyle("content_scripts/menu.css", null, this.xShadowMenuNode); + this.xShadowMenuNode.appendChild(this.xMenu); + this._insertAfter(this.xShadowMenu, xNodeInsertAfter, nMarginTop + 8); + } else { + let nMarginTop = -1 * (8 + parseInt(xStyle.marginBottom.replace('px', ''), 10)); + if (!document.getElementById("grammalecte_cssmenu")) { + oGrammalecte.createStyle("content_scripts/menu.css", "grammalecte_cssmenu", document.head); + } + this._insertAfter(this.xButton, xNodeInsertAfter, nMarginTop); + this._insertAfter(this.xMenu, xNodeInsertAfter, nMarginTop + 8); + } this._createListeners(); } _insertAfter (xNewNode, xReferenceNode, nMarginTop) { xReferenceNode.parentNode.insertBefore(xNewNode, xReferenceNode.nextSibling); @@ -31,10 +54,13 @@ xNewNode.style.marginTop = nMarginTop + "px"; } _createListeners () { this.xNode.addEventListener('focus', (e) => { + if (this.bShadow) { + this.xShadowBtn.style.display = "block"; + } this.xButton.style.display = "block"; }); /*this.xNode.addEventListener('blur', (e) => { window.setTimeout(() => {this.xButton.style.display = "none";}, 300); });*/ @@ -47,10 +73,13 @@ _createMenu () { try { let xMenu = oGrammalecte.createNode("div", {id: this.sMenuId, className: "grammalecte_menu"}); let xCloseButton = oGrammalecte.createNode("div", {className: "grammalecte_menu_close_button", textContent: "×"} ); xCloseButton.onclick = () => { + if (this.bShadow){ + this.xShadowBtn.style.display = "none"; + } this.xButton.style.display = "none"; this.switchMenu(); } xMenu.appendChild(xCloseButton); xMenu.appendChild(oGrammalecte.createNode("div", {className: "grammalecte_menu_header", textContent: "GRAMMALECTE"})); @@ -113,13 +142,21 @@ showError(e); } } deleteNodes () { - this.xMenu.parentNode.removeChild(this.xMenu); - this.xButton.parentNode.removeChild(this.xButton); + if (this.bShadow) { + this.xShadowMenu.parentNode.removeChild(this.xShadowMenu); + this.xShadowBtn.parentNode.removeChild(this.xShadowBtn); + } else { + this.xMenu.parentNode.removeChild(this.xMenu); + this.xButton.parentNode.removeChild(this.xButton); + } } switchMenu () { + if (this.bShadow) { + this.xShadowMenu.style.display = (this.xShadowMenu.style.display == "block") ? "none" : "block"; + } this.xMenu.style.display = (this.xMenu.style.display == "block") ? "none" : "block"; } } 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,29 @@ // JavaScript // Panel creator +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global oGrammalecte, xGrammalectePort, showError, window, document, console */ + "use strict"; class GrammalecteMessageBox { constructor (sId, sTitle) { this.sId = sId; + + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; + if (this.bShadow) { + this.xShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"}); + this.xShadow = this.xShadowPanel.attachShadow({mode: "open"}); + this.xParent = this.xShadow; + } else { + this.xParent = 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 +62,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){ + oGrammalecte.createStyle("content_scripts/panel.css", null, this.xShadow); + oGrammalecte.createStyle("content_scripts/message_box.css", null, this.xShadow); + this.xShadow.appendChild(this.xMessageBox); + document.body.appendChild(this.xShadowPanel); + } else { + if (!document.getElementById("grammalecte_cssmsg")){ + oGrammalecte.createStyle("content_scripts/panel.css", null, document.head); + oGrammalecte.createStyle("content_scripts/message_box.css", "grammalecte_cssmsg", document.head); + } + 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,8 +1,12 @@ // JavaScript // Panel creator +/* jshint esversion:6, -W097 */ +/* jslint esversion:6 */ +/* global GrammalectePanel, oGrammalecte, xGrammalectePort, showError, window, document, console */ + "use strict"; class GrammalectePanel { @@ -9,10 +13,20 @@ constructor (sId, sTitle, nWidth, nHeight, bFlexible=true) { this.sId = sId; this.nWidth = nWidth; this.nHeight = nHeight; this.bFlexible = bFlexible; + + this.bShadow = document.body.createShadowRoot || document.body.attachShadow; + if (this.bShadow) { + this.xShadowPanel = oGrammalecte.createNode("div", {id: this.sId+"_shadow", style: "width:0;height:0;"}); + this.xShadow = this.xShadowPanel.attachShadow({mode: "open"}); + this.xParent = this.xShadow; + } else { + this.xParent = 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 +95,26 @@ 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) { + oGrammalecte.createStyle("content_scripts/panel.css", null, this.xShadow); + oGrammalecte.createStyle("content_scripts/panel_gc.css", null, this.xShadow); + oGrammalecte.createStyle("content_scripts/panel_lxg.css", null, this.xShadow); + oGrammalecte.createStyle("content_scripts/panel_tf.css", null, this.xShadow); + this.xShadow.appendChild(this.xPanel); + document.body.appendChild(this.xShadowPanel); + } else { + if (!document.getElementById("grammalecte_csspanel")) { + oGrammalecte.createStyle("content_scripts/panel.css", "grammalecte_csspanel", document.head); + oGrammalecte.createStyle("content_scripts/panel_gc.css", null, document.head); + oGrammalecte.createStyle("content_scripts/panel_lxg.css", null, document.head); + oGrammalecte.createStyle("content_scripts/panel_tf.css", null, document.head); + } + document.body.appendChild(this.xPanel); + } } show () { this.xPanel.style.display = "block"; } @@ -137,11 +166,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.xParent, 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.xParent.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.xParent.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.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Analyse…"; + this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(0, 50%, 50%)"; + this.xParent.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.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).textContent = "Réanalyser"; + this.xParent.getElementById("grammalecte_check"+xParagraph.dataset.para_num).style.backgroundColor = "hsl(120, 30%, 50%)"; + this.xParent.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.xParent.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.xParent.getElementById("grammalecte_err" + sErrorId); + xNodeErr.textContent = this.xParent.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.xParent.getElementById(sIgnoreButtonId).dataset.error_id; + let xNodeErr = this.xParent.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.xParent.getElementById("grammalecte_clipboard_button"); xClipboardButton.textContent = "->>"; let sText = ""; - for (let xNode of document.getElementsByClassName("grammalecte_paragraph")) { + for (let xNode of this.xParent.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 (xParent, xContentNode) { + this.xParent = xParent; 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.xParent.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.xParent.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.xParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message.slice(0, n); + this.xParent.getElementById("grammalecte_tooltip_rule_id").textContent = "Règle : " + xNodeErr.dataset.gc_message.slice(n+2); + this.xParent.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.xParent.getElementById("grammalecte_tooltip_message").textContent = xNodeErr.dataset.gc_message; + this.xParent.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.xParent.getElementById("grammalecte_tooltip_url").dataset.url = xNodeErr.dataset.gc_url; + this.xParent.getElementById("grammalecte_tooltip_url").style.display = "inline"; } else { - document.getElementById("grammalecte_tooltip_url").dataset.url = ""; - document.getElementById("grammalecte_tooltip_url").style.display = "none"; + this.xParent.getElementById("grammalecte_tooltip_url").dataset.url = ""; + this.xParent.getElementById("grammalecte_tooltip_url").style.display = "none"; } - document.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; + this.xParent.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.xParent.getElementById("grammalecte_tooltip_message").textContent = "Mot inconnu du dictionnaire."; + this.xParent.getElementById("grammalecte_tooltip_ignore").dataset.error_id = xNodeErr.dataset.error_id; + this.xParent.getElementById("grammalecte_tooltip_rule_id").style.display = "none"; + this.xParent.getElementById("grammalecte_tooltip_url").dataset.url = ""; + this.xParent.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.xParent.getElementById("grammalecte_tooltip_db_search").style.display = "inline"; + this.xParent.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.xParent.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.xParent.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.xParent.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 xPanelContent = this.xParent.getElementById('grammalecte_panel_content'); + for (let xNode of xPanelContent.getElementsByClassName(sClass)) { xNode.hidden = bHidden; } } } Index: gc_lang/fr/webext/content_scripts/panel_tf.css ================================================================== --- gc_lang/fr/webext/content_scripts/panel_tf.css +++ gc_lang/fr/webext/content_scripts/panel_tf.css @@ -111,10 +111,11 @@ div#grammalecte_tf_reset:hover { background-color: hsl(210, 50%, 40%); } progress#grammalecte_tf_progressbar { width: 360px; + height: 29px; } span#grammalecte_tf_time_res { width: 60px; padding: 5px 10px; } 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.xParent.getElementById(sOptName).dataset.selected == "true") { + this.xParent.getElementById(sOptName.slice(2)).style.opacity = 1; } else { - document.getElementById(sOptName.slice(2)).style.opacity = 0.3; + this.xParent.getElementById(sOptName.slice(2)).style.opacity = 0.3; } this.resetProgressBar(); } switchOption (sOptName) { - let xOption = document.getElementById(sOptName); + let xOption = this.xParent.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.xParent.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.xParent.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.xParent.getElementById('grammalecte_tf_progressbar').value = 0; + this.xParent.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.xParent.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.xParent.getElementById("res_"+xOption.id) !== null) { + this.xParent.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.xParent.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.xParent.getElementById(sOptName)) { + return (this.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.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.xParent.getElementById('grammalecte_tf_progressbar').value = this.xParent.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.xParent.getElementById('grammalecte_tf_time_res').textContent = this.getTimeRes((t1-t0)/1000); this.xTextArea.value = sText; } catch (e) { showError(e); } Index: gc_lang/fr/webext/manifest.json ================================================================== --- gc_lang/fr/webext/manifest.json +++ gc_lang/fr/webext/manifest.json @@ -46,18 +46,10 @@ "exclude_matches": [ "*://*.wikisource.org/*", "*://*.wikipedia.org/*", "*://*.wiktionary.org/*" ], - "css": [ - "content_scripts/panel.css", - "content_scripts/panel_tf.css", - "content_scripts/panel_gc.css", - "content_scripts/panel_lxg.css", - "content_scripts/message_box.css", - "content_scripts/menu.css" - ], "js": [ "content_scripts/panel.js", "grammalecte/fr/textformatter.js", "content_scripts/panel_tf.js", "content_scripts/panel_gc.js", @@ -72,17 +64,10 @@ "matches": [ "*://*.wikisource.org/*", "*://*.wikipedia.org/*", "*://*.wiktionary.org/*" ], - "css": [ - "content_scripts/panel.css", - "content_scripts/panel_tf.css", - "content_scripts/panel_gc.css", - "content_scripts/panel_lxg.css", - "content_scripts/menu.css" - ], "js": [ "content_scripts/panel.js", "grammalecte/fr/textformatter.js", "content_scripts/panel_tf.js", "content_scripts/panel_gc.js", @@ -114,10 +99,15 @@ "description": "Ouvre l’éditeur lexical" } }, "web_accessible_resources": [ + "content_scripts/panel.css", + "content_scripts/panel_tf.css", + "content_scripts/panel_gc.css", + "content_scripts/panel_lxg.css", + "content_scripts/menu.css", "grammalecte/graphspell/_dictionaries/fr-allvars.json", "grammalecte/graphspell/_dictionaries/fr-classic.json", "grammalecte/graphspell/_dictionaries/fr-reform.json", "grammalecte/fr/conj_data.json", "grammalecte/fr/mfsp_data.json",